30

挑战:最短的代码,按字符计数,检测并删除字符串中的重复字符。删除包括重复字符的所有实例(因此,如果您找到 3 个 n,则所有三个都必须删除),并且需要保留原始字符顺序。

示例输入 1:
nbHHkRvrXbvkn

示例输出 1:
RrX


示例输入 2:
nbHHkRbvnrXbvkn

示例输出 2:
RrX

(第二个示例删除了出现三次的字母;一些解决方案未能解决此问题)

(这是基于我的另一个问题,我需要在 C# 中以最快的方式执行此操作,但我认为它可以跨语言制作良好的 Code Golf。)

4

48 回答 48

38

LabVIEW 7.1

一个字符,即框图中的蓝色常量“ 1 ”。我发誓,输入是复制和粘贴 ;-)

http://i25.tinypic.com/hvc4mp.png

http://i26.tinypic.com/5pnas.png

于 2009-08-31T20:14:43.580 回答
26

Perl

perl 的 21 个字符,调用 31 个字符,总共 36 个击键(计算移位和最终返回):

perl -pe's/$1//gwhile/(.).*\1/'
于 2009-08-28T00:16:10.277 回答
19

红宝石 — 61 53 51 56 35

61 个字符,统治者说。(给了我另一个代码高尔夫的想法……)

  puts ((i=gets.split(''))-i.select{|c|i.to_s.count(c)<2}).join
+-------------------------------------------------------------------------+
||    |    |    |    |    |    |    |    |    |    |    |    |    |    |  |
|0         10        20        30        40        50        60        70 |
|                                                                         |
+-------------------------------------------------------------------------+
  gets.chars{|c|$><<c[$_.count(c)-1]}

... 35 由 Nakilon

于 2009-08-28T07:20:33.613 回答
18

APL

23 个字符:

(((1+ρx)-(ϕx)ιx)=xιx)/x

我是 APL 新手(昨天才知道),所以请客气——这当然不是最有效的方法。我很惭愧我没有击败 Perl。

再说一次,当一个新手在 APL 中解决这个问题的最自然的方法仍然比迄今为止任何语言中的任何其他解决方案更简洁时,也许它说明了什么。

于 2009-08-29T16:11:58.790 回答
15

Python:

s=raw_input()
print filter(lambda c:s.count(c)<2,s)

这是一个完整的工作程序,可以读写控制台。单行版本可以直接从命令行使用

python -c 's=raw_input();print filter(lambda c:s.count(c)<2,s)'
于 2009-08-28T00:14:31.087 回答
14

J(16 12 个字符)

(~.{~[:I.1=#/.~)

例子:

(~.{~[:I.1=#/.~) 'nbHHkRvrXbvkn'
    RrX

它只需要括号默认执行。如果放在动词中,实际代码本身将是 14 个字符。

当然有更聪明的方法可以做到这一点。

编辑:有问题的更聪明的方式:

(~.#~1=#/.~) 'nbHHkRvrXbvkn'
    RrX

12 个字符,如果设置在动词中,则只有 10 个。我仍然讨厌它遍历列表两次的事实,一次用于计数 (#/.),另一次用于返回唯一值(nub 或 ~.),但即使是 nubcount,'misc' 库中的标准动词也会执行两次。

于 2010-02-10T15:45:19.530 回答
12

哈斯克尔

在 Haskell 中肯定有更短的方法可以做到这一点,但是:

Prelude Data.List> let h y=[x|x<-y,(<2).length$filter(==x)y]
Prelude Data.List> h "nbHHkRvrXbvkn"
"RrX"

忽略 let,因为它只是 GHCi 中的函数声明所必需的,所以我们有h y=[x|x<-y,(<2).length$filter(==x)y]37 个字符(这与 的当前“核心”Python 相关联"".join(c for c in s if s.count(c)<2),无论如何它实际上是相同的代码)。

如果你想用它制作一个完整的程序,

h y=[x|x<-y,(<2).length$filter(==x)y]
main=interact h

$ echo "nbHHkRvrXbvkn" | runghc tmp.hs
RrX

$ wc -c tmp.hs
54 tmp.hs

或者我们可以这样敲掉一个字符:

main=interact(\y->[x|x<-y,(<2).length$filter(==x)y])

$ echo "nbHHkRvrXbvkn" | runghc tmp2.hs
RrX

$ wc -c tmp2.hs
53 tmp2.hs

它在所有标准输入上运行,而不是逐行运行,但这似乎可以接受 IMO。

于 2009-08-28T02:03:35.200 回答
9

C89(106 个字符)

这个使用与我原来的答案完全不同的方法。有趣的是,写完之后再看另一个答案,我发现方法非常相似。感谢 caf 在我之前提出这种方法。

b[256];l;x;main(c){while((c=getchar())>=0)b[c]=b[c]?1:--l;
for(;x-->l;)for(c=256;c;)b[--c]-x?0:putchar(c);}

一行是 58+48 = 106 bytes

C89(173 个字符)

这是我原来的答案。正如评论中所说,它不太好用......

#include<stdio.h>
main(l,s){char*b,*d;for(b=l=s=0;l==s;s+=fread(b+s,1,9,stdin))b=realloc(b,l+=9)
;d=b;for(l=0;l<s;++d)if(!memchr(b,*d,l)&!memchr(d+1,*d,s-l++-1))putchar(*d);}

在两行中,它是 17+1+78+77 = 173 bytes

于 2009-08-28T00:31:16.560 回答
8

C#

65 个字符:

new String(h.Where(x=>h.IndexOf(x)==h.LastIndexOf(x)).ToArray());

67 个重新分配的字符:

h=new String(h.Where(x=>h.IndexOf(x)==h.LastIndexOf(x)).ToArray());
于 2009-08-28T06:54:45.087 回答
7

C#

new string(input.GroupBy(c => c).Where(g => g.Count() == 1).ToArray());

71 个字符

于 2009-08-28T00:11:27.123 回答
6

PHP (136 characters)

<?PHP
function q($x){return $x<2;}echo implode(array_keys(array_filter(
array_count_values(str_split(stream_get_contents(STDIN))),'q')));

On one line, it's 5+1+65+65 = 136 bytes. Using PHP 5.3 you could save a few bytes making the function anonymous, but I can't test that now. Perhaps something like:

<?PHP
echo implode(array_keys(array_filter(array_count_values(str_split(
stream_get_contents(STDIN))),function($x){return $x<2;})));

That's 5+1+66+59 = 131 bytes.

于 2009-08-28T22:44:20.530 回答
6

另一个 APL 解决方案

作为动态函数(18 个字符)

{(1+=/¨(ω∘∊¨ω))/ω}

假设输入在变量 x(16 个字符)中的行:

(1+=/¨(x∘∊¨x))/x
于 2009-09-17T10:56:57.973 回答
5

电源外壳

61 个字符。结果在哪里$s="nbHHkRvrXbvkn",在哪里$a

$h=@{}
($c=[char[]]$s)|%{$h[$_]++}
$c|%{if($h[$_]-eq1){$a+=$_}}

功能齐全的参数化脚本:

param($s)
$h=@{}
($c=[char[]]$s)|%{$h[$_]++}
$c|%{if($h[$_]-eq1){$a+=$_}}
$a
于 2009-08-28T07:44:07.717 回答
5

Golfscript(sym) - 15

  .`{\{=}+,,(!}+,
+-------------------------------------------------------------------------+
||    |    |    |    |    |    |    |    |    |    |    |    |    |    |  |
|0         10        20        30        40        50        60        70 |
|                                                                         |
+-------------------------------------------------------------------------+
于 2010-02-11T22:26:13.163 回答
5

VB.NET

For Each c In s : s = IIf(s.LastIndexOf(c) <> s.IndexOf(c), s.Replace(CStr(c), Nothing), s) : Next

诚然,VB 不是尝试保存字符的最佳语言,但该行最多 98 个字符。

于 2009-08-28T02:02:30.333 回答
5

C: 8389 93 99 101人物

  • O(n 2 ) 时间。
  • 限制为 999 个字符。
  • 仅在 32 位模式下工作(由于 not #include-ing <stdio.h>(花费 18 个字符)使返回类型gets被解释为 anint并砍掉一半的地址位)。
  • 显示一个友好的“警告:此程序使用gets(),这是不安全的。” 在 Mac 上。

.

main(){char s[999],*c=gets(s);for(;*c;c++)strchr(s,*c)-strrchr(s,*c)||putchar(*c);}

(这个类似的82 -chars 版本通过命令行输入:

main(char*c,char**S){for(c=*++S;*c;c++)strchr(*S,*c)-strrchr(*S,*c)||putchar(*c);}

)

于 2010-02-10T14:43:36.613 回答
4

哈斯克尔

(只是从 Mark Rushakoff 的努力中删除了几个字符,我宁愿将它作为对他的评论发布)

h y=[x|x<-y,[_]<-[filter(==x)y]]

这是更好的 Haskell 习语,但对于非 Haskell 人来说可能比这更难遵循:

h y=[z|x<-y,[z]<-[filter(==x)y]]

编辑以添加对 hiena 和其他人的解释:

我假设您理解 Mark 的版本,所以我将只介绍更改。马克的表情:

(<2).length $ filter (==x) y

过滤y以获取元素列表== x,找到该列表的长度并确保它小于两个。(实际上它必须是长度一,但==1比 长<2) 我的版本:

[z] <- [filter(==x)y]

执行相同的过滤器,然后将结果列表作为唯一元素放入列表中。现在箭头(看起来像集合包含!)说“对于 RHS 列表的每个元素,依次调用该元素[z]”。[z]是包含单个元素的列表z,因此元素“ filter(==x)y”只有在[z]它包含一个元素时才能称为“”。否则它会被丢弃并且永远不会用作 的值z。所以z's(在列表理解的左侧返回|)正是x使filterreturn 成为长度为 1 的列表的 's。

那是我的第二个版本,我的第一个版本返回x而不是z- 因为它们无论如何都是相同的 - 并重命名z_“这个值不会被使用,所以我不会使我的代码复杂化”的 Haskell 符号通过给它一个名字”。

于 2009-08-31T02:00:45.163 回答
3

Javascript 1.8

s.split('').filter(function (o,i,a) a.filter(function(p) o===p).length <2 ).join('');

或者 - 类似于 python 示例:

[s[c] for (c in s) if (s.split("").filter(function(p) s[c]===p).length <2)].join('');
于 2009-08-28T01:00:35.473 回答
3

汇编器

使用 WinXP DOS 框 (cmd.exe) 测试:

    xchg cx,bp
    std
    mov al,2
    rep stosb
    inc cl
l0: ; to save a byte, I've encoded the instruction to exit the program into the
    ; low byte of the offset in the following instruction:
    lea si,[di+01c3h] 
    push si
l1: mov dx,bp
    mov ah,6
    int 21h
    jz l2
    mov bl,al
    shr byte ptr [di+bx],cl
    jz l1
    inc si
    mov [si],bx
    jmp l1
l2: pop si
l3: inc si
    mov bl,[si]
    cmp bl,bh
    je l0+2
    cmp [di+bx],cl
    jne l3
    mov dl,bl
    mov ah,2
    int 21h
    jmp l3

汇编为 53 个字节。读取标准输入并将结果写入标准输出,例如:

 programname < input > output
于 2010-02-11T11:46:50.003 回答
3

红宝石

63 个字符。

puts (t=gets.split(//)).map{|i|t.count(i)>1?nil:i}.compact.join
于 2009-08-28T03:50:52.770 回答
3

TCL

123 个字符。有可能让它更短,但这对我来说已经足够了。

proc h {i {r {}}} {foreach c [split $i {}] {if {[llength [split $i $c]]==2} {set r $r$c}}
return $r}
puts [h [gets stdin]]
于 2009-08-28T03:03:07.620 回答
3

VB.NET/LINQ

96 个字符的完整工作声明

Dim p=New String((From c In"nbHHkRvrXbvkn"Group c By c Into i=Count Where i=1 Select c).ToArray)

完整的工作语句,带有原始字符串和 VB 特定的“漂亮列表(代码重新格式化”)关闭,在 96 个字符处,没有原始字符串的非工作语句在 84 个字符处。

(请确保您的代码在回答之前有效。谢谢。)

于 2009-08-28T03:56:25.863 回答
3

C

完整的 C 语言程序,141 字节(包括换行符)。

#include<stdio.h>
c,n[256],o,i=1;main(){for(;c-EOF;c=getchar())c-EOF?n[c]=n[c]?-1:o++:0;for(;i<o;i++)for(c=0;c<256;c++)n[c]-i?0:putchar(c);}
于 2009-08-28T06:03:34.330 回答
3

Javascript 1.6

s.match(/(.)(?=.*\1)/g).map(function(m){s=s.replace(RegExp(m,'g'),'')})

比之前发布的 Javascript 1.8 解决方案更短(71 个字符与 85 个字符)

于 2010-01-26T19:41:26.323 回答
3

斯卡拉

54 个字符仅用于方法主体,66 个带有(静态类型)方法声明:

def s(s:String)=(""/:s)((a,b)=>if(s.filter(c=>c==b).size>1)a else a+b)
于 2009-08-28T04:22:28.277 回答
3

C

(第一版:112 个字符;第二版:107 个字符)

k[256],o[100000],p,c;main(){while((c=getchar())!=-1)++k[o[p++]=c];for(c=0;c<p;c++)if(k[o[c]]==1)putchar(o[c]);}

那是

/* #include <stdio.h> */
/* int */ k[256], o[100000], p, c;
/* int */ main(/* void */) {
  while((c=getchar()) != -1/*EOF*/) {
    ++k[o[p++] = /*(unsigned char)*/c];
  }
  for(c=0; c<p; c++) {
    if(k[o[c]] == 1) {
      putchar(o[c]);
    }
  }
  /* return 0; */
}

因为 getchar() 返回 int 而 putchar 接受 int,所以可以“安全地”删除 #include。没有包含,EOF 没有定义,所以我使用 -1 代替(并获得了一个字符)。该程序仅适用于少于 100000 个字符的输入!

版本 2,感谢 strager 107 个字符

#ifdef NICE_LAYOUT
#include <stdio.h>

/* global variables are initialized to 0 */
int char_count[256];                          /* k in the other layout */
int char_order[999999];                       /* o ... */
int char_index;                               /* p  */

int main(int ch_n_loop, char **dummy)         /* c  */
                                              /* variable with 2 uses */
{

  (void)dummy; /* make warning about unused variable go away */

  while ((ch_n_loop = getchar()) >= 0) /* EOF is, by definition, negative */
  {
    ++char_count[ ( char_order[char_index++] = ch_n_loop ) ];
    /* assignment, and increment, inside the array index */
  }
  /* reuse ch_n_loop */
  for (ch_n_loop = 0; ch_n_loop < char_index; ch_n_loop++) {
    (char_count[char_order[ch_n_loop]] - 1) ? 0 : putchar(char_order[ch_n_loop]);
  }
  return 0;
}
#else
k[256],o[999999],p;main(c){while((c=getchar())>=0)++k[o[p++]=c];for(c=0;c<p;c++)k[o[c]]-1?0:putchar(o[c]);}
#endif
于 2009-08-29T16:06:54.747 回答
2

sed,41 个字符

:;s/((.).*\2.*)\2/\1/;t;s/(.)(.*)\1/\2/;t

用法:$ echo nbHHkRbvnrXbvkn | sed -r ':;s/((.).*\2.*)\2/\1/;t;s/(.)(.*)\1/\2/;t'

gnarf pyon 贡献;)。

于 2010-02-11T22:37:14.580 回答
2

C#(53 个字符)

其中 s 是您的输入字符串:

new string(s.Where(c=>s.Count(h=>h==c)<2).ToArray());

或 59 重新分配:

var a=new string(s.Where(c=>s.Count(h=>h==c)<2).ToArray());
于 2010-02-10T15:06:52.427 回答
2

Shell/Coreutils,37 个字符

fold -w1|sort|uniq -u|paste -s -d ''
于 2010-02-11T00:20:36.423 回答
2

PHP

118 个字符的实际代码(加上 PHP 块标记的 6 个字符):

<?php
$s=trim(fgets(STDIN));$x='';while(strlen($s)){$t=str_replace($s[0],'',substr($s,1),$c);$x.=$c?'':$s[0];$s=$t;}echo$x;
于 2009-08-31T21:09:34.500 回答
2

Haskell Pointfree

import Data.List
import Control.Monad
import Control.Arrow
main=interact$liftM2(\\)nub$ap(\\)nub

整个节目97个字,但真正的肉只有23个字。其余的只是导入并将函数带入 IO monad。在加载了模块的 ghci 中,它只是

(liftM2(\\)nub$ap(\\)nub) "nbHHkRvrXbvkn"

在更荒谬的无点风格(无意义的风格?):

main=interact$liftM2 ap liftM2 ap(\\)nub

虽然函数本身有 26 个字符,但它有点长。

于 2010-02-10T15:54:08.410 回答
2

百合池,78 个字符

z=#(ly:gulp-file"A")#(print(string-delete z(lambda(x)(>(string-count z x)1))))

用法:$ cp input.in A; lilypond this.ly

于 2010-02-11T23:10:11.210 回答
1

D2(模板):195197 199+ 17 个字符

template F(alias s,int c,int i){static if(s>"")enum F=F!(s[1..$],c,i-(s[0]==c));else enum F=i?s:s~c;}template M(alias s,alias t=s){static if(s>"")enum M=F!(t,s[0],1)~M!(s[1..$],t);else enum M=s;}

扩展:

template F(alias s,int c,int i){
    static if(s>"")
        enum F=F!(s[1..$],c,i-(s[0]==c));
    else
        enum F=i?s:s~c;
}
template M(alias s,alias t=s){
    static if(s>"")
        enum M=F!(t,s[0],1)~M!(s[1..$],t);
    else
        enum M=s;
}

pragma(msg,M!"nbHHkRvrXbvkn");
于 2010-02-10T14:23:10.483 回答
1

使用 C - 118 个字符

我认为这个答案很好,因为它适用于任何字符串长度。

main(int s,char *a[]){int i=0,j,c,d;while(s=c=a[1][i]){j=0;while(d=a[1][j])if(i!=j++)if(c==d)s=0;s&&putchar(c);i++;}}

并且通过删除变量的类型定义,可以将其降至 105(我认为是新的 C 赢家:P),但我的编译器会抛出错误!

你们有什么感想?

于 2010-02-02T02:36:36.730 回答
1

卢阿

98 个字符的函数,115 个字符的完整程序

f以最易读的格式编写,g旨在以f更简洁的方式准确再现。

小写fg函数是“详细”的,大写FG“压缩的”版本。

J与 相同G,但它被声明为显示完整程序所需的字符数。

removedups.lua

f = function(s)
    h=s:sub(1,1) -- head of string
    r=s:sub(2)   -- rest of string
    if r:find(h) then -- first character is repeated
        return f(s:gsub(h, '')) -- f(rest without any instance of h)
    elseif r > "" then -- there is something left in the rest of the string
        return h .. f(r) -- concatenate head with f(rest)
    else return h -- rest is empty string, so just return value left in head
    end
end

F=function(s)h=s:sub(1,1)r=s:sub(2)if r:find(h)then return f(s:gsub(h,''))elseif r>""then return h ..f(r)else return h end end
--       1         2         3         4         5         6         7         8         9        10        11        12
--3456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
-- 126 chars, compressed

g = function(s)
    h=s:sub(1,1)
    r=s:sub(2)
    return (r:find(h) and g(s:gsub(h, '')) or (r > "" and h .. g(r)) or h)
end

G=function(s)h=s:sub(1,1)r=s:sub(2)return r:find(h)and g(s:gsub(h,''))or(r>""and h ..g(r))or h end
--       1         2         3         4         5         6         7         8         9        10        11     
--345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
-- 98 chars, compressed

-- code-golf unit tests :)
assert(f("nbHHkRvrXbvkn")=="RrX")
assert(F("nbHHkRvrXbvkn")=="RrX")
assert(g("nbHHkRvrXbvkn")=="RrX")
assert(G("nbHHkRvrXbvkn")=="RrX")

J=function(s)h=s:sub(1,1)r=s:sub(2)return r:find(h)and g(s:gsub(h,''))or(r>""and h ..g(r))or h end print(J(arg[1]))
--       1         2         3         4         5         6         7         8         9        10        11     
--34567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
-- 115 chars, full program

输出:

$ lua 删除ups.lua nbHHkRvrXbvkn
RrX
于 2009-09-16T01:32:52.457 回答
1

欣快感

来自非常冗长的语言的 165 个字符。

object c=getc(0),r={},b=r
while c>0 do
if find(c,r)then b&=c end if
r&=c
c=getc(0)
end while
for i=1 to length(r)do
if find(r[i],b)=0 then puts(1,r[i])end if
end for
于 2009-08-31T15:44:36.233 回答
1

sed/Java

具有30 个字符的 sed 版本,如果不包含命令的调用,则为21 个字符:

sed -r ':_;s/(.)(.*)\1/\2/;t_'

一个使用相同想法的java版本(应该都写在一行中),它​​是157个字符:

class T{public static void main(String[]a){String s=a[0];int l;
do{l=s.length();s=s.replaceAll("(.)(.*)\\1","$2");}while(s.length()<l);
System.out.printf(s);}}
于 2009-08-31T17:23:14.643 回答
1

Lua,91 个字符

i,s=1,...s:gsub('.',function(c)if s:find(c,i)then s=s:gsub(c,'')else i=i+1 end end)print(s)
于 2010-11-18T11:37:21.667 回答
0

OCaml,93 个字符(wc -c)。

open String
let f s=let r=ref""in iter(fun c->if not(contains!r c)then r:=!r^(make 1 c))s;!r
于 2010-08-30T14:09:57.013 回答
0

F#,94 个字符

let f(a:string)=new string(Seq.toArray(Seq.filter(fun(c:char)->a.IndexOf c=a.LastIndexOf c)a))
printfn "%s" (f "nbHHkRvrXbvkn")
于 2010-08-31T00:23:30.100 回答
0
#!/usr/bin/python

# Python, 67 characters, in a giant generator.
f=lambda s:''.join([c for c in s if len([d for d in s if d==c])<2])

string = "nbHHkRvrXbvkn"
print f(string) => "RrX"
于 2010-08-30T23:11:44.797 回答
0

Python,50 个字符(基于 SHiNKiROU 67 个字符版本)

f=lambda s:''.join([c for c in s if s.count(c)<2])
于 2010-10-02T16:29:28.020 回答
0

Lua,97 个字符

i=...repeat c=i:match("(.).-%1")i=c and i:gsub(c:gsub("(%W)","%%%1"),"")or i until not c print(i)
于 2010-02-10T22:40:12.180 回答
0

D 编程语言第 2 版,68 个字符:

auto f(S)(S s){return array(filter!((a){return s.count(a)<2;})(s));}
于 2010-02-10T23:00:39.390 回答
0

GW-BASIC - 117 个字符

1INPUT I$:FOR I=1 TO LEN(I$):S$=MID$(I$,I,1):C=0
2P=INSTR(P+1,I$,S$):C=C-(P>0):IF P GOTO 2
3IF C=1 THEN ?S$;
4NEXT
于 2010-03-11T06:34:08.113 回答
0

F#,使用列表的非代码高尔夫版本:

16 ilnes 使用列表:

let rec removefromlist v l = 
    match l with 
    | h::t -> 
        let (res, removed) = removefromlist v t
        if h = v then (res, true)
        else (h::res, removed)
    | [] -> ([], false)
let rec removedups unique tail = 
    match tail with
    | h::t -> 
        let (u_res, u_removed) = removefromlist h unique
        let (t_res, t_removed) = removefromlist h t
        if (t_removed || u_removed) then removedups u_res t_res
        else h::removedups u_res t_res
    | [] -> []
removedups [] (Array.toList("nbHHkRvrXbvkn".ToCharArray()));;

F# - 185 个字符- 没有列表的更简洁的版本:

let s = "nbHHkRvrXbvkn"
let n c (s:string)=
    let mutable i = 0
    for x in 0..s.Length-1 do
        if s.[x]=c then i<-i+1
    i
String.collect (fun c -> if n c s>1 then "" else c.ToString()) s
于 2010-02-12T10:34:36.767 回答
0

翔升:23

args1[;{},,\=/+1=]""z P

ASL 是我制作的受 Golfscript 启发的脚本语言。

于 2011-02-05T15:56:11.097 回答
-2

我找不到原始答案,但本着 Jon Skeet 的回答:

跳闸:

退休储蓄计划

该程序的含义是:从标准输入(R)读取一个字符串,去除所有重复字符(S),将结果打印到标准输出(P)。

于 2009-08-28T00:32:38.137 回答