击倒PPCG用户名


32

我在聊天室中进行评论以及随后的谈话激发了我挑战这一挑战。

我是这里唯一的缩写缩写人吗?我们都在打高尔夫球。我们可以有MB和D-nob以及...O。

如果我被称为“ CH”,那么我认为其他所有人也应该有一个以缩写开头的昵称。

以下是按声誉使用的排名前100位的编程难题和代码高尔夫用户的列表:

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

这就是我的方法

挑战

编写一个程序或函数,该程序或函数接受一个字符串列表,然后输出另一个字符串列表,这些字符串的最小,唯一,基于初始的昵称,优先于列表开头的那些。

按照给定创建昵称的顺序,将此方法应用于列表中的每个字符串S:

  1. 将S拆分为用空格分隔的单词,删除该过程中的所有空格。
  2. 列出S中单词的第一个字母的字符串的非空前缀,从最短到最长。
    例如Just Some NameJJSJSN
  3. 在列表中选择与已经选择的昵称不同的第一项作为S的昵称。如果选择了昵称,请停止,否则继续执行步骤4。
    例如,如果Just Some Name是第一个字符串,则J保证是昵称。
  4. 再次列出前缀,但是这自然包括第一个单词的第二个字母。
    例如Just Some NameJuJuSJuSN
  5. 为此列表执行第3步中的操作,如果找到唯一的昵称,则停止。
  6. 对第一个单词的其余字母重复此过程,最后将字母插入第二个单词,然后第三个单词,依此类推,直到找到唯一的昵称。
    例如,在这里列出的第一个唯一的字符串将是绰号:
    JusJusSJusSN
    JustJustSJustSN
    JustJustSoJustSoN(注意,o后不加Just
    JustJustSomJustSomN
    JustJustSomeJustSomeN
    JustJustSomeJustSomeNa
    JustJustSomeJustSomeNam
    JustJustSomeJustSomeName

最后,所有输入字符串应以唯一的昵称结尾(可能与字符串相同)。您可以假定使用此方法,没有任何输入字符串将映射到相同的昵称。

更新以解决我的错误!

对于输入

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

昵称是

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

细节

  • 输入可以来自文件(每行一个名称),也可以一次通过stdin /命令行输入一个名称,或者作为字符串列表的函数自变量,或者作为单个字符串的函数arg,名称之间带有换行符。
  • 输出应打印到标准输出(每行一个昵称),或者由函数以字符串列表形式返回,或者作为一个在昵称之间带有换行符的字符串返回。
  • 理想情况下,程序将适用于包含除行终止符之外的任何字符的名称。但是,您可以假定所有名称仅包含可打印的ASCII。(PPCG名称没有。)
  • 只有常规空格字符才算作单词分隔符。前导和尾随空格可以忽略。

计分

以字节为单位的最短提交获胜。Tiebreaker转到最早发布的答案。


49
这解释了为什么我在半夜醒来时被这种模糊的感觉侵犯了。
马丁·恩德

Answers:


8

CJam,58 53字节

这可以打很多球。但是对于初学者来说:

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

代码扩展

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

在这里在线尝试


2
请参阅我对OP的评论:如果'Ju'或'Jus'是'Just Some Name','Maertin Butter'的有效昵称,则为'Ma',然后是'MaB','Mar','MarB'。
edc65

@ edc65说的是真的。对于那个很抱歉。如果您愿意,我将不允许您更改任何内容;是我的错
加尔文的爱好

9

JavaScript(ES6)159

遵循规格而非示例。

我生成具有当前中间单词(开头是第一个单词)的候选昵称。当前之前的单词按“原样”使用。当前单词之后的单词没有-或只是第一个字符。当前单词为每个循环另外贡献1个字符。

例如, '只是一些名称'=> '你', '有些', '名称'
CW Just,位置1,尝试JJSJSN
CW Just,位置2,尝试JuJuSJuSN
CW Just,位置3,尝试JusJusSJusSN
CW Just,位置4,尝试JustJustSJustSN
现在Just已耗尽,Some变成Cw,位置重新设置为2(对于位置1,已全部尝试)

CW Some,位置2,尝试JustJustSoJustSoN
CW Some,位置3,尝试JustJustSomJustSomN
CW Some,位置4,尝试JustJustSomeJustSomeN
现在Some是精疲力竭,Name成为CW,位置重新开始至2

CW Name,位置2,尝试JustJustSomeJustSomeNa
CW Name,位置3,尝试JustJustSomeJustSomeNam
CW Name,位置4,尝试JustJustSomeJustSomeName
这是所有乡亲!

代码

(q是当前单词位置,p是切片位置)

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

在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“]


2

PHP,327 289 275 274 270

高尔夫运动仍有一定潜力。

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,'
';}
  • 程序在stdin / stdout上运行,在ASCII上运行,在UTF上运行错误
  • 用法: php -d error_reporting=0 golfnicks.php < nicknames.txt
  • cat <<EOF | php -d error_reporting=0 golfnicks.php+名称清单+EOF
  • 要在Web浏览器中测试其功能,请执行以下操作:获取细目,取消注释所有标有的行,// FUNC并注释标有的行//PROG。尝试f(array_fill(0,21,'Just Some Name'));

分解

#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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.