Golf W dół nazwy użytkownika PPCG

32

Komentarz zrobiłem na czacie i związane z nim rozmowa zainspirowała mnie do tego wyzwania.

Czy jestem tu jedynym, o którym wspominają inicjały? Chcemy grać w golfa. Możemy mieć MB i D-nob i ... O.

Jeśli jestem znany jako „CH”, myślę, że wszyscy inni powinni mieć również pseudonim początkowy.

Oto lista 100 najlepszych łamigłówek programistycznych i użytkowników Code Golf według reputacji do zabawy:

Martin Büttner
Doorknob
Peter Taylor
Howard
marinus
Dennis
DigitalTrauma
David Carraher
primo
squeamish ossifrage
Keith Randall
Ilmari Karonen
Quincunx
Optimizer
grc
Calvin's Hobbies
ugoren
Mig
gnibbler
Sp3000
aditsu
histocrat
Ventero
xnor
mniip
Geobits
J B
Joe Z.
Gareth
Jan Dvorak
isaacg
edc65
Victor
steveverrill
feersum
ace
Danko Durbić
xfix
PhiNotPi
user23013
manatwork
es1024
Joey
daniero
boothby
nneonneo
Joey Adams
Timwi
FireFly
dansalmo
grovesNL
breadbox
Timtech
Flonk
algorithmshark
Johannes Kuhn
Yimin Rong
copy
belisarius
professorfish
Ypnypn
trichoplax
Darren Stone
Riot
ProgramFOX
TheDoctor
swish
minitech
Jason C
Tobia
Falko
PleaseStand
VisioN
leftaroundabout
alephalpha
FUZxxl
Peter Olson
Eelvex
marcog
MichaelT
w0lf
Ell
Kyle Kanos
qwr
flawr
James_pic
MtnViewMark
cjfaure
hammar
bitpwner
Heiko Oberdiek
proud haskeller
dan04
plannapus
Mr Lister
randomra
AShelly
ɐɔıʇǝɥʇuʎs
Alexandru
user unknown

( tak to dostałem )

Wyzwanie

Napisz program lub funkcję, która pobiera listę ciągów i wyświetla kolejną listę ciągów ich minimalnych, unikalnych pseudonimów początkowych, dając pierwszeństwo tym, które są bliżej początku listy.

Zastosuj tę metodę do każdego łańcucha S na liście w podanej kolejności, aby utworzyć pseudonimy:

  1. Podziel S na słowa oddzielone spacjami, usuwając wszystkie spacje w procesie.
  2. Wymień niepuste prefiksy ciągu pierwszych liter słów w S, od najkrótszego do najdłuższego.
    np Just Some NameJ, JS,JSN
  3. Wybierz pierwszy element z tej listy, który nie jest identyczny z już wybranym pseudonimem jako pseudonim dla S. Zatrzymaj się, jeśli pseudonim został wybrany, przejdź do kroku 4 w przeciwnym razie.
    np. jeśli Just Some Namebył pierwszym ciągiem, Jgwarantujemy, że będzie to pseudonim.
  4. Ponownie wypisz prefiksy, ale tym razem dołącz drugą literę pierwszego słowa w jego naturalnym miejscu.
    np Just Some NameJu, JuS,JuSN
  5. Zrób to samo, co w kroku 3 dla tej listy, zatrzymując się, jeśli zostanie znaleziony unikalny pseudonim.
  6. Powtórz ten proces z pozostałymi literami pierwszego słowa, ostatecznie wstawiając litery do drugiego słowa, a następnie trzeciego i tak dalej, aż do znalezienia unikalnego pseudonimu.
    np Pierwszy unikalny ciąg wymienione tutaj będzie nick:
    Jus, JusS, JusSN
    Just, JustS, JustSN
    Just, JustSo, JustSoN(uwaga, że onie został dodany po Just)
    Just, JustSom, JustSomN
    Just, JustSome, JustSomeN
    Just, JustSome, JustSomeNa
    Just, JustSome, JustSomeNam
    Just, JustSome,JustSomeName

Na koniec wszystkie łańcuchy wejściowe powinny kończyć się unikalnym pseudonimem (potencjalnie identycznym z łańcuchem). Możesz założyć, że żaden z łańcuchów wejściowych nie będzie mapowany na ten sam pseudonim przy użyciu tej metody.

Przykład

Zaktualizowano, aby naprawić mój błąd!

Dla danych wejściowych

Martin Buttner
Doorknob
Peter Taylor
Howard
marinus
Dennis
DigitalTrauma
David Carraher
Martin Bitter
Martin Butter
Martin Battle
Martini Beer
Mart Beer
Mars Bar
Mars Barn

będą to przezwiska

M
D
P
H
m
De
Di
DC
MB
Ma
MaB
Mar
MarB
Mars
MarsB

Detale

  • Dane wejściowe mogą pochodzić z pliku (jedna nazwa w wierszu), lub jedna nazwa na raz za pośrednictwem wiersza polecenia stdin /, lub jako argument funkcji listy ciągów lub jako argument funkcji pojedynczego ciągu z nowymi liniami między nazwami.
  • Dane wyjściowe powinny być wypisywane na standardowe wyjście (jeden pseudonim na linię) lub zwracane przez funkcję jako lista ciągów znaków lub jako jeden ciąg znaków z nowymi liniami między pseudonimami.
  • Idealnie programy będą działały dla nazw zawierających dowolne znaki z wyjątkiem terminatorów linii . Można jednak założyć, że wszystkie nazwy zawierają tylko drukowalne ASCII . (Nazwy PPCG nie.)
  • Tylko znak zwykłej spacji liczy się jako separator słów. Wiodące i końcowe spacje można zignorować.

Punktacja

Najkrótsze przesłanie w bajtach wygrywa. Tiebreaker przechodzi do odpowiedzi wysłanej najwcześniej.

Hobby Calvina
źródło
49
To wyjaśnia, dlaczego obudziłem się w środku nocy z tym niejasnym uczuciem naruszenia.
Martin Ender

Odpowiedzi:

8

CJam, 58 53 bajtów

Można w to dużo grać w golfa. Ale na początek:

LqN/{:Q1<aQ,,:)QS/f{{1$<_,@-z1e>}%W<s}+{a1$&!}=a+}/N*

Rozszerzenie kodu :

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";

Wypróbuj online tutaj

Optymalizator
źródło
2
Zobacz mój komentarz do OP: jeśli „Ju” lub „Jus” są poprawnymi pseudonimami „Just Some Name”, „Maertin Butter” powinien być „Ma”, a następnie „MaB”, „Mar”, „MarB”.
edc65
To, co mówi @ edc65, jest prawdą. Przepraszam za to. Pozwolę ci nie zmieniać rzeczy, jeśli chcesz; to był mój błąd.
Calvin's Hobbies
9

JavaScript (ES6) 159

Zgodnie ze specyfikacjami, a nie z przykładem.

Generuję pseudonimy kandydatów posiadające bieżące środkowe słowo (na początku pierwsze słowo). Słowa przed prądem są używane „tak jak jest”. Słowa po bieżącym przyczyniają się do braku - lub tylko pierwszego - znaku. Bieżące słowo ma 1 dodatkowy znak dla każdej pętli.

Przykład 'tylko niektóre Nazwa' => 'Tak', 'Niektóre', 'Nazwa'
Cw Just, pozycja 1, spróbuj J, JS, JSN
Cw Just, pozycja 2, spróbuj Ju, JuS, JuSN
Cw Just, pozycja 3, spróbuj Jus, JusS, JusSN
Cw Just, pozycja 4, spróbuj Just, JustS, JustSN
teraz Justjest wyczerpany , Somestaje się Cw, pozycja zrestartowana do 2 (dla pozycji 1, wszystkie już wypróbowane)

Cw Some, pozycja 2, spróbuj Just, JustSo, JustSoN
cw Some, pozycja 3, spróbuj Just, JustSom, JustSomN
cw Some, pozycja 4, spróbuj Just, JustSome, JustSomeN
teraz Somejest wyczerpany, Namestaje Cw, stanowisko do 2 wznowiona

Cw Name, pozycja 2, spróbuj Just, JustSome, JustSomeNa
cw Name, pozycja 3, spróbuj Just, JustSome, JustSomeNam
cw Name, pozycja 4, spróbuj Just, JustSome, JustSomeName
to wszystko ludzie!

Kod

(q oznacza aktualną pozycję słowa, p oznacza pozycję krojenia)

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

Przetestuj w konsoli Firefox / FireBug

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 ”]

edc65
źródło
2

PHP, 327 289 275 274 270

Wciąż może być mały potencjał golfowy.

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 działa na stdin / stdout, działa na ASCII, buggy na UTF
  • stosowanie: php -d error_reporting=0 golfnicks.php < nicknames.txt
  • lub cat <<EOF | php -d error_reporting=0 golfnicks.php+ lista nazw +EOF
  • Aby przetestować jako funkcję w przeglądarce internetowej: pobierz rozkład, odkomentuj wszystkie linie oznaczone // FUNCi skomentuj linię oznaczoną //PROG. Próbowaćf(array_fill(0,21,'Just Some Name'));

awaria

#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
Tytus
źródło