Golf Down the PPCG Usernames
JavaScript (ES6) 159
Following the specs and not the example.
I generate the candidate nicknames having a current middle word (at the beginning, the first word). The words before the current are used 'as is'. The words after the current contribute with no - or just the first - character. The current word contributes with 1 more character for each loop.
Example 'Just Some Name' => 'Just','Some','Name'
Cw Just
, position 1
, try J
, JS
, JSN
Cw Just
, position 2
, try Ju
, JuS
, JuSN
Cw Just
, position 3
, try Jus
, JusS
, JusSN
Cw Just
, position 4
, try Just
, JustS
, JustSN
Now Just
is exhausted, Some
becomes Cw, position restarted to 2 (for position 1, all already tried)
Cw Some
, position 2
, try Just
, JustSo
, JustSoN
Cw Some
, position 3
, try Just
, JustSom
, JustSomN
Cw Some
, position 4
, try Just
, JustSome
, JustSomeN
Now Some
is exhausted, Name
becomes Cw, position restarted to 2
Cw Name
, position 2
, try Just
, JustSome
, JustSomeNa
Cw Name
, position 3
, try Just
, JustSome
, JustSomeNam
Cw Name
, position 4
, try Just
, JustSome
, JustSomeName
That's all folks!
The code
(q is current word position, p is slicing position)
F=l=>
l.map(w=>{
for(w=w.match(/[^ ]+/g),q=p=0;
w.every((w,i)=>~o.indexOf(t+=i<q?w:i>q?w[0]:w.slice(0,p+1)),t='')
&&(w[q][p++]||(p=1,w[++q]));
);
o.push(t)
},o=[])&&o
Test In Firefox/FireBug console
F(['Martin Buttner','Doorknob','Peter Taylor','Howard','marinus'
,'Dennis','DigitalTrauma','David Carraher'
,'Martin Bitter','Martin Butter','Martin Battle','Martini Beer','Mart Beer'])
["M", "D", "P", "H", "m", "De", "Di", "DC", "MB", "Ma", "MaB", "Mar", "MarB"]
CJam, 58 53 bytes
This can be golfed a lot.. But for starters:
LqN/{:Q1<aQ,,:)QS/f{{1$<_,@-z1e>}%W<s}+{a1$&!}=a+}/N*
Code Expansion:
L "Put an empty array on stack. This is the final nickname array";
qN/{ ... }/ "Read the input and split it on new lines. Run the block for each";
:Q1<a "Store each name in Q and get its first char. Wrap it in an array";
Q,,:) "Get an array of 1 to length(name) integers";
QS/ "Split the name on spaces";
f{{ }% } "for each of the integer in the array, run the code block";
"and then for each of the name part, run the inner code block";
1$< "Copy the integer, take first that many characters from the";
"first part of the name";
_,@-z1e> "Get the actual length of the part and the number of characters";
"to be taken from the next name part, minimum being 1";
W< "Get rid of the last integer which equals 1";
s "Concat all name parts in the array";
+ "Add the list of nick names as per spec with the first character";
{ }= "Get the first nick name that matches the criteria";
a1$& "Wrap the nick name in an array and do set intersection with";
"the copy of existing nick names";
! "Choose this nick name if the intersection is empty";
N* "After the { ... }/ for loop, the stack contains the final";
"nick names array. Print it separated with new lines";
Try it online here
PHP, 327 289 275 274 270
There may still be a little golfing potential.
while($n=fgets(STDIN)){$c=count($w=preg_split('/\s+/',trim($n)));$p=[];for($k=0;$k<$c;$p[$k]++){for($t='',$j=0;$j<$c;$j++)$t.=substr($w[$j],0,$p[$j]+1);for($j=1;$j<=strlen($t);$j++)if(!in_array($v=substr($t,0,$j),$u))break 2;$k+=$p[$k]==strlen($w[$k]);}echo$u[]=$v,'
';}
- Program operates on stdin/stdout, works on ASCII, buggy on UTF
- usage:
php -d error_reporting=0 golfnicks.php < nicknames.txt
- or
cat <<EOF | php -d error_reporting=0 golfnicks.php
+ list of names +EOF
- To test as function in web browser: fetch the breakdown, uncomment all lines marked with
// FUNC
and comment the one marked with//PROG
. Tryf(array_fill(0,21,'Just Some Name'));
breakdown
#error_reporting(0);function f($a){echo'<pre>'; // FUNC
#foreach($a as$n) // FUNC
while($n=fgets(STDIN)) // PROG
{
$c=count($w=preg_split('/\s+/',trim($n))); // split name to words, count them
$p=[]; // initialize cursors
for($k=0;$k<$c;$p[$k]++)
{
for($t='',$j=0;$j<$c;$j++)$t.=substr($w[$j],0,$p[$j]+1); // concatenate prefixes
for($j=1;$j<=strlen($t);$j++) // loop through possible nicks
if(!in_array($v=substr($t,0,$j),$u)) // unused nick found
break 2; // -> break cursor loop
$k+=$p[$k]==strlen($w[$k]); // if Cw exhausted -> next word
// strlen()-1 would be correct; but this works too)
}
echo$u[]=$v,'
';
}
#echo '</pre>';} // FUNC