输入uniqchars!


41

给定一个包含可打印ASCII字符的字符串,请按原始顺序产生一个包含其唯一字符的输出。换句话说,输出与输入相同,不同之处在于如果以前出现过char,则将其删除。

不能使用用于在数组中查找唯一元素的内置unique函数(例如,MATLAB具有执行此操作的功能)。这个想法是手动完成的。

更多详情:

  • 允许使用功能或程序
  • 输入和输出可以采用函数参数,stdin / stdout(甚至对于函数)的形式,也可以混合使用。
  • 如果使用stdin或stdout,则将字符串理解为chars序列。如果使用函数自变量,则可能需要将字符序列在引号或等效符号中,以供选择的编程语言定义字符串。
  • 输出应该是仅包含输入的唯一字符的字符串。因此,没有多余的换行符,空格等。唯一的例外是:如果输出在stdout中显示,则大多数显示函数都会添加尾随\n(将字符串与接下来的内容分开)。因此在stdout中可以接受一个尾随\n
  • 如果可能,请发布一个指向在线解释器/编译器的链接,以便其他人可以尝试您的代码。

这是代码高尔夫,因此以字节为单位的最短代码获胜。

假设stdin和stdout的一些示例

  1. 输入字符串:

    Type unique chars!
    

    输出字符串:

    Type uniqchars!
    
  2. 输入字串

    "I think it's dark and it looks like rain", you said
    

    输出字符串

    "I think'sdarloe,yu
    
  3. 输入字串

    3.1415926535897932384626433832795
    

    输出字符串

    3.14592687
    

5
只是要仔细检查:“没有内置”规则是否意味着不允许设置对象?
Sp3000 2015年

允许使用@ Sp3000 Set对象。只是不要使用为您提供其独特元素的函数或方法(如果存在)。并且输入/输出应该是字符串,而不是tobject
Luis

@ Sp3000如果不使用set函数,将字节数减少一半会更有趣吗?还是在挑战确定后就不更改规则?
Luis Mendo 2015年

5
我认为目前只有我的答案使用集合,如果您更改了它,我也不会介意。但是,我不太确定这样的奖金是否会发生很大变化,例如,我怀疑CJam是否可以在<6个字节的情况下不设置任何设置。另外,我不确定在找到唯一元素的内置函数和由多个元素构造一个集合之间的界线在哪里……
Sp3000,2015年

1
@ Sp3000是的,边框模糊。我没想到设置函数。我想我会
摆脱

Answers:


13

GolfScript,2个字节

.&

或者,或者:

.|

不久前,我在“ GolfScript线程中打高尔夫球技巧”中发布了此内容。它的工作方式是复制输入字符串(由GolfScript解释器自动将其放入堆栈,并且在大多数情况下的行为类似于字符数组),然后将其自身的设置交集(&)或并集(|)合并。将set运算符应用于数组(或字符串)会折叠所有重复项,但会保留元素的顺序。


23

CJam,3个字节

qL|

使用空列表输入或逐项输入。CJam设置操作保留元素顺序。

在线尝试


我假设这是有效的,因为允许使用集,但是我不确定...
Sp3000,2015年

非常聪明!我知道CJam是最好的之一,但是我没想到只有3个字节!
路易斯·门多

19

C#6,18 + 67 = 85字节

需要以下using语句:

using System.Linq;

实际方法:

string U(string s)=>string.Concat(s.Where((x,i)=>s.IndexOf(x)==i));

此方法通过将函数定义为lambda来节省一些字符,这在C#6中受支持。这就是它在C#6之前的版本中的样子(但不完整):

string Unique(string input)
{
    return string.Concat(input.Where((x, i) => input.IndexOf(x) == i));
}

工作原理:我用带有两个参数的lambda 调用字符串上的Where方法x代表当前元素,i代表该元素的索引。IndexOf总是返回传递给它的char的第一个索引,因此,如果i不等于的第一个索引x,则它是重复的char,因此不能包含在内。


3
老实说,我不会期望C#这么短。很棒的工作!
Alex A.

嗯 我认为您应该提交完整的程序(包括static void Main等等)。
Timwi

3
@Timwi此挑战指出“允许使用任何功能或程序”。
hvd 2015年

C#还允许使用LINQ的更短方法。我已经发布了一个有竞争性的答案。:)
hvd 2015年

@hvd不错!+1
ProgramFOX 2015年

14

视网膜,14字节

+`((.).*)\2
$1

每一行应放入其自己的单独文件中,或者您可以使用该-s标志从一个文件中读取。

为了说明这一点,我们将使用以下更长但更简单的版本:

+`(.)(.*)\1
$1$2

第一行是要匹配的正则表达式(+`是配置字符串,它将一直运行,直到完成所有替换为止)。正则表达式会查找字符(我们将其称为C),后跟零个或多个任意字符,后跟C。括号表示捕获组,因此我们将匹配项替换为C($1),并将匹配项替换为($2),删除C的副本。

例如,如果输入的字符串是unique,在第一次运行将匹配uniqu,以uniq作为$1$2,分别。然后,它会替换为原始输入匹配的子字符串uniq,给人uniqe


3
我正在寻找一个正则表达式来做到这一点;我没意识到它这么短!+1
ETHproductions 2015年

13

Perl,21(20字节+ -p

s/./!$h{$&}++&&$&/eg

用法:

perl -pe 's/./!$h{$&}++&&$&/eg' <<< 'Type unique chars!'
Type uniqchars!

1
您可以保存1个字节,取反$h{$&}并使用逻辑AND代替三元运算符:s/./!$h{$&}++&&$&/eg
kos 2015年

@kos如果您问过我,我会告诉您我100%尝试过此操作,并1在输出中以s 结尾,但事实并非如此!谢谢更新!
唐·黑斯廷斯

1
已经支持:)我想您已经尝试过s/./$h{$&}++||$&/eg(起初我也很喜欢)。不好意思,因为那本来是另一个保存的字节。
kos 2015年

11

通心粉0.0.2,233字节

set i read set f "" print map index i k v return label k set x _ set _ slice " " length index f e 1 1 set f concat f wrap x return label e set _ slice " " add _ multiply -1 x 1 1 return label v set _ unwrap slice i _ add 1 _ 1 return
  • 创建“反高尔夫”语言:检查
  • 反正高尔夫:检查

这是一个完整的程序,从STDIN输入,在STDOUT输出。

包装版本,具有美学价值:

set i read set f "" print map index i k v return label k set x _ set _ slice "
" length index f e 1 1 set f concat f wrap x return label e set _ slice " " add
_ multiply -1 x 1 1 return label v set _ unwrap slice i _ add 1 _ 1 return

还有一个高度“注释”的版本(通心粉中没有注释,因此我只使用裸字符串文字):

set input read                  "read line from STDIN, store in 'input' var"
set found ""                    "we need this for 'keep' below"
print map index input keep val  "find indeces to 'keep', map to values, print"
return

label keep
    "we're trying to determine which indeces in the string to keep. the special
     '_' variable is the current element in question, and it's also the value
     to be 'returned' (if the '_' variable is '0' or empty array after this
     label returns, the index of the element is *not* included in the output
     array; otherwise, it is"
    set x _ set _ slice
        " "
        length index found exists
        1
        1
    "now we're using 'index' again to determine whether our '_' value exists in
     the 'found' array, which is the list of letters already found. then we
     have to apply a boolean NOT, because we only want to keep values that do
     NOT exist in the 'found' array. we can 'invert' a boolean stored as an
     integer number 'b' (hence, 'length') with 'slice(' ', b, 1, 1)'--this is
     equivalent to ' '[0:1], i.e. a single-character string which is truthy, if
     'b' was falsy; otherwise, it results in an empty string if 'b' was truthy,
     which is falsy"
    set found concat found wrap x  "add the letter to the 'found' array"
return

label exists
    set _ slice
        " "
        add _ multiply -1 x
        1
        1
    "commentary on how this works: since 0 is falsy and every other number is
     truthy, we can simply subtract two values to determine whether they are
     *un*equal. then we apply a boolean NOT with the method described above"
return

label val
    set _ unwrap slice input _ add 1 _ 1  "basically 'input[_]'"
return

(这是第一个真正的通心粉程序(实际上可以执行某些操作)!\ o /)


5
•给该语言取一个有趣且恰当的名称:检查
Luis Mendo

11

的JavaScript ES7,37个 33 25字节

使用ES6 Set和ES7 数组推导运算符的简单方法:

s=>[...new Set(s)].join``

比该indexOf方法少22个字节。处理了一些测试用例。


for表达式周围的空格不是必需的,您可以像其他解决方案一样使它成为匿名函数:s=>[for(c of Set(s))c].join``。(更新:不是100%肯定,但该new关键字似乎也没有必要。)
manatwork

不确定具有匿名功能的规则,以及对空间的把握。
azz

Transpiled代码而不new导致Uncaught TypeError: Constructor Set requires 'new'谷歌浏览器。
azz

请原谅我的无知,但是在什么时候过滤唯一值?看起来它只是将字符串转换为数组,然后将值重新连接为原始字符串。
Patrick Roberts

@PatrickRoberts这是到一组的转换。一组由定义中没有dupluicates
edc65

8

C#6-18 + 46 = 64

using System.Linq;

接着

string f(string s)=>string.Concat(s.Union(s));

Enumerable.Union该元件中的原始顺序返回扩展方法规定了:

枚举此方法返回的对象时,Union 依次枚举第一个第二个,并产生尚未产生的每个元素。

并非专门用于查找唯一值的set操作似乎可以通过其他答案来判断。


不错,我当时在想,string u(string s)=>String.Join("",s.Distinct());但这要更长一些。
杰米

@germi谢谢。已经有一个使用的答案Distinct(),但是由于Distinct()在此挑战中不允许使用,因此将其删除,因为这是一种专门用于查找唯一值的方法。
hvd 2015年

啊,对了...忽略了那一点;)
杰米

是否s => string.Concat(s.Union(s))有效?那将是Func<string, string>作为参数传递给a的委托。
Tyler StandishMan

@TylerStandishMan如果这是正确的,我希望更多的人可以使用它,而且我以前从未见过,所以我认为它不是。但这也许是有效的-如果您有兴趣,这似乎值得在Meta上进行检查。
hvd

7

JavaScript ES6,47个字节

f=s=>s.replace(/./g,(e,i)=>s.indexOf(e)<i?'':e)

以下测试适用于所有浏览器。

f=function(s){
  return s.replace(/./g,function(e,i){
    return s.indexOf(e)<i?'':e
  })
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('input').value)};document.getElementById('run').onclick=run;run()
<input type="text" id="input" value="Type unique chars!" /><button id="run">Run</button><br />
<pre id="output"></pre>


<i?'':e零件做什么?
DanTheMan

1
这是一个三元运算符。如果一个字符的第一个实例e在当前索引之前i,它将返回一个空字符串,从而摆脱该字符。如果那是第一个实例,它只会返回e而不会进行任何更改。
NinjaBearMonkey 2015年

7

MATLAB,23

 @(n)union(n,n,'stable')

使用不排序的“稳定”方法对输入字符串本身进行“设置并集”,然后打印。

之所以union可行,是因为合并后仅返回非重复值。因此,从本质上讲,如果您union使用字符串本身,它将首先生成类似的字符串Type unique chars!Type unique chars!,然后删除所有重复项而不进行排序。

不需要unique:)


unique不允许,对不起!这是具有挑战性的定义
Luis Mendo 2015年

错过了,没关系。
汤姆·卡彭特

遵循Sp3000的答案,我可以建议setdiff使用该'stable'选项吗?
Luis Mendo 2015年

1
真好!是的,您可以删除它,disp因为这样您就有了一个返回字符串的函数,这是允许的
Luis Mendo 2015年

1
您也可以使用intersectwith 'stable'达到相同的效果。我本来要写的,但是给出这个答案,它不再是原始的笑声了。
rayryeng-恢复莫妮卡2015年

7

> <>,16个字节

i:0(?;:::1g?!o1p

> <>没有字符串,因此我们使用了代码框。由于> <>的环形特性,以下循环运行:

i         Read a char
:0(?;     Halt if EOF
:::       Push three copies of the char
1g        Get the value at (char, 1), which is 0 by default
?!o       Print the char if the value was nonzero
1p        Set the value at (char, 1) to char

请注意,这利用了输入仅包含可打印ASCII的事实,因为如果存在ASCII 0,这将不起作用。


1
.......这太棒了。我希望我已经想到了这一点。我将在答案中包含一个Befunge版本,但不作为主要版本。编辑:再三考虑,这将不起作用,因为Befunge没有无限的代码空间。该死的!
El'endia Starman

@ El'endiaStarman我认为Beam的回答也有同样的作用,所以不幸的是我不能说我是第一次:P
Sp3000 2015年

嗯,是的,我认为您是对的。您的解释比较清楚。
El'endia Starman 2015年


5

元素22 19 18字节

_'{"(3:~'![2:`];'}

输入/输出示例:hello world->helo wrd

这可以通过简单地一次处理一个字符串并跟踪以前看到过的字符来工作。

_'{"(3:~'![2:`];'}
_                        input line
 '                       use as conditional
  {              }       WHILE loop
   "                     retrieve string back from control (c-) stack
    (                    split to get the first character of (remaining) string
     3:                  a total of three copies of that character
       ~                 retrieve character's hash value
        '                put on c-stack
         !               negate, gives true if undef/empty string
          [   ]          FOR loop
           2:`           duplicate and output
               ;         store character into itself
                '        put remaining string on c-stack as looping condition


4

Python 3、44

r=''
for c in input():r+=c[c in r:]
print(r)

r逐个字符地构建输出字符串,c仅当我们尚未看到输入字符串时才包括输入中的字符。

Python 2将是47,使用会丢失4个字符,raw_input并在不需要解析器的情况下节省1 个字符print


现在的共识似乎是您可以input在Python 2中使用,因此您可以将其缩短一个字节。
mbomb007 '16

4

APL,3

∊∪/

这将在向量的每个元素之间应用并集(∪),从而获得具有删除重复项效果的迭代。

tryapl.org上进行测试

旧的:

~⍨\

这将在参数的每个元素之间使用〜(带有反向参数,使用⍨)。结果是,对于每个元素,如果已在列表中,则将其删除。


细说:“而且输入/输出应该是字符串”。“ Unione reduce”返回嵌套数组,而不是字符串。O :-)
lstefano

没错,请在开头加上∊进行更正。
莫里斯·祖卡

3

Perl,54 27字节

map{$h{$_}||=print}<>=~/./g
123456789012345678901234567

测试:

$ echo Type unique chars! | perl -e 'map{$h{$_}||=print}<>=~/./g'
Type uniqchars!
$

1
print exists($h{$_})?"":$_$h{$_}||print
manatwork'2015-10-4

SO是否已在其中插入unicode→char使其损坏?
2012年

1
使用statement修饰符可以节省一些字节,以及@manatwork的建议$h{$_}||=print,使用<>=~/./g应该也可以节省更多!
Dom Hastings 2015年

1
不,我插入了它,意思是“更改为”。
manatwork'2015-10-4

1
更改为map,还可以提高节省的map{$h{$_}||=print}<>=~/./g
余地

3

PHP,72字节 84字节

<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));

将字符用作关联数组的键,然后打印键。数组元素的顺序始终是插入顺序。

感谢Ismael Miguel的str_split建议。


1
<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));较短,且相同。
伊斯梅尔·米格尔

找到了一个较短的循环:while($c=$argv[1][$i++*1])。这取代了整体foreach。其他所有内容都一样
Ismael Miguel

我首先尝试了类似的方法,但不要这样做,因为它会停在强制为“ false”(即)的字符上"0"。尝试将“ abc0def”作为输入。
Fabian Schmengler,2015年

你是对的。Surelly有一个不超过2个字节的解决方法。
伊斯梅尔·米格尔

3

Pyth,7个字节

soxzN{z

伪代码:

z =输入

在z的集合中N的z中的按序索引的总和。


3

朱莉娅,45 42字节

s->(N="";[i∈N?N:N=join([N,i])for i=s];N)

旧版本:

s->(N={};for i=s i∈N||(N=[N,i])end;join(N))

代码通过在其上附加新字符来构建新字符串,然后在最后将join它们一起添加到适当的字符串中。新版本通过数组理解迭代来保存一些字符。还使用?:而不是节省了一个字节||(因为这样就消除了分配中括号的需要)。

使用递归和正则表达式的替代解决方案,45字节:

f=s->s!=(s=replace(s,r"(.).*\K\1",""))?f(s):s

朱莉娅,17个字节

(替代版本)

s->join(union(s))

union基本上可以代替unique-我不认为这是“真正的”答案,因为我将“不要使用unique” 解释为“不要使用具有返回唯一值的效果的单个内置函数”元素”。


我有一个类似的想法,但并不那么简洁。干得好!
Alex A.

3

Java,78个字节

String f(char[]s){String t="";for(char c:s)t+=t.contains(c+"")?"":c;return t;}

一个简单的循环,同时检查输出中是否存在字符。接受输入作为char[]


3

C,96字节

#include<stdio.h> 
int c,a[128];main(){while((c=getchar())-'\n')if(!a[c])a[c]=1,putchar(c);}

这使用整数数组,并按ASCII字符编号索引。仅当数组中的该位置设置为FALSE时才打印字符。找到每个新字符后,将数组中的位置设置为TRUE。这将从标准输入中获取一行文本,并以换行符终止。它忽略非ASCII字符。


取消高尔夫:

#include<stdio.h>
#include<stdbool.h>

int main(void)
{
  int i, c;
  int ascii[128];
  for (i = 0; i < 128; ++i) {
    ascii[i] = false;
  }
  while ((c = getchar()) != '\n') {
    if (ascii[c] == false) {
      ascii[c] = true;
      putchar(c);
    }
  }
  puts("\n");
  return(0);
}

3

C-58

感谢@hvd和@AShelly节省了一堆字符。有多种方法可以使它比原始方法短得多:

// @hvd     - always copy to q but only increment q if not found
g(char*s,char*r){char*q=r;for(;*q=*s;q+=q==strchr(r,*s++));}

// @AShelly - keep a histogram of the usage of each character
h(char*s){int a[128]={0};for(;*s;s++)a[*s]++||putchar(*s);}

// @hvd     - modify in place
i(char*s){char*q=s,*p=s;for(;*q=*p;q+=q==strchr(s,*p++));}

// original version - requires -std=c99
void f(char*s,char*r){for(char*q=r;*s;s++)if(!strchr(r,*s))*q++=*s;}

如您所见,就地修改似乎是最短的(到目前为止!) gcc test.c

#include <stdlib.h> // calloc
#include <string.h> // strchr
#include <stdio.h>  // puts, putchar

// 000000111111111122222222223333333333444444444455555555556666666666
// 456789012345678901234567890123456789012345678901234567890123456789

// @hvd     - always copy to q but only increment q if not found
g(char*s,char*r){char*q=r;for(;*q=*s;q+=q==strchr(r,*s++));}

// @AShelly - keep a histogram of the usage of each character
h(char*s){int a[128]={0};for(;*s;s++)a[*s]++||putchar(*s);}

// @hvd     - modify in place
i(char*s){char*q=s,*p=s;for(;*q=*p;q+=q==strchr(s,*p++));}

/* original version - commented out because it requires -std=c99
void f(char*s,char*r){for(char*q=r;*s;s++)if(!strchr(r,*s))*q++=*s;}
*/

// The test program:
int main(int argc,char*argv[]){
  char *r=calloc(strlen(argv[1]),1); // make a variable to store the result
  g(argv[1],r);                      // call the function
  puts(r);                           // print the result

  h(argv[1]);                        // call the function which prints result
  puts("");                          // print a newline

  i(argv[1]);                        // call the function (modifies in place)
  puts(argv[1]);                     // print the result
}

感谢您的所有帮助。我感谢所有缩短建议的建议!


好吧,由于您的代码已经不是有效的C语言,因此被宽松的C编译器接受:您可以声明rint(并省略int)来保存一些字节:f(s,r)char*s;{...}。但这将您的代码限制char*在与大小相同的平台上int,当然,在与您本人一样宽容的编译器上也是如此。
2015年

@hvd太邪恶了!我愿意默认返回值,因为我不使用它。但这比我想要的要狡猾。我想我宁愿使它合规而不是走那么远!感谢您回到光明的一面。
杰里·耶利米

您可以if(x)yx?y:0
ugoren

这是一个60 char函数,它写入stdout而不是数组参数: f(char*s){int a[128]={0};for(;*s;s++)a[*s]++?0:putchar(*s);}
AShelly

您可以无条件地复制到中*q,并且仅q在字符出现较早时才递增,从而可以填充得更多:(void f(char*s,char*r){for(char*q=r;*q=*s;strchr(r,*s++)<q||q++);}请注意,strchr(r,*s++)<q定义始终良好,那里没有UB,因为在该版本中strchr无法返回NULL。)除了返回类型,它甚至比@AShelly的版本短。
hvd 2015年

2

Ruby,30个 24个字符

(23个字符的代码+ 1个字符的命令行选项。)

gsub(/./){$`[$&]?"":$&}

样品运行:

bash-4.3$ ruby -pe 'gsub(/./){$`[$&]?"":$&}' <<< 'hello world'
helo wrd

2

CJam,9岁

Lq{1$-+}/

这不会将字符串转换为集合,但是会执行一种集合差异以确定是否在字符串中找到字符。在线尝试

说明:

L       push an empty array/string
q       read the input
{…}/    for each character in the input
  1$    copy the previous string
  -     subtract from the character (set difference),
         resulting in the character or empty string
  +     append the result to the string

另一个版本,13个字节:

Lq{_2$#)!*+}/

这与集合无关。在线尝试

说明:

L       push an empty array/string
q       read the input
{…}/    for each character in the input
  _     duplicate the character
  2$    copy the previous string
  #)    find the index of the character in the string and increment it
  !     negate, resulting in 0 if the character was in the string and 1 if not
  *     repeat the character that many times
  +     append the result to the string

2

TI-BASIC,49字节

Input Str1
"sub(Str1,X,1→Y₁
Y₁(1
For(X,2,length(Str1
If not(inString(Ans,Y₁
Ans+Y₁
End
Ans

方程变量很少有用,因为它们要存储5个字节,但Y₁在此方便用作X字符串的th个字符,节省了3个字节。由于不能在TI-BASIC中添加空字符串,因此我们从Str1的第一个字符开始,然后遍历字符串的其余部分,添加所有尚未遇到的字符。

prgmQ
?Why no empty st
rings? Because T
I...
Why noemptysrig?Bcau.

2

Matlab,46个字节

它使用匿名函数,函数参数作为输入和输出:

@(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')

(我无法在Octave在线解释器中使用它。)

使用示例:

>> @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')
ans = 
    @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')

>> ans('Type unique chars!')
ans =
Type uniqchars!

那也应该是我的主意:)-您不需要,1with any,顺便说一句。
乔纳斯(Jonas)

@乔纳斯谢谢!尽管很难看清括号中的内容,但这1是因为triu (我需要删除对角线),而不是因为any
Luis Mendo

2

Befunge -93,124个字节

v
<v1p02-1
0_v#`g00: <0_@#+1::~p
 1>:1+10p2+0g-!#v_v
g `#v_10g0^       >:10g00
 ^0g 00$        <
 ^  >:,00g1+:00p1+:1+01-\0p

此在线解释器中对其进行测试。


这比我预期的要难。如果有人要我明天将发布更详细的解释,但这是我的代码功能的概述。

  • 到目前为止看到的唯一字符存储在第一行,2,0从右开始并向右扩展。对照此命令检查当前字符是否重复。
  • 到目前为止,已看到的唯一字符数存储在中0,0,而重复检查循环计数器则存储在中1,0
  • 当看到一个唯一字符时,它将存储在第一行中,打印出来,然后0,0递增计数器。
  • 为避免读取存在的空格(ASCII 32)时出现问题,我将对应于-1的字符(实际上是65536)放入下一个唯一字符的下一个插槽中。

2

PHP, 56 54

// 56 bytes
<?=join('',array_flip(array_flip(str_split($argv[1]))));

// 54 bytes
<?=join(!$a='array_flip',$a($a(str_split($argv[1]))));

两次使用@fschmengler的答案array_flip -第二个版本使用变量方法,并依赖于将字符串强制转换为true,将其否定为false,然后将其强制转换回第一个参数中的空字符串,以在第二个参数中保存几个字节。贱!


2

Haskell,29个字节

可嵌套的无变量单线:

foldr(\x->(x:).filter(x/=))[]

计数相同,保存到名为f顶级声明的函数中:

f(x:t)=x:f[y|y<-t,x/=y];f_=[]

请注意,有一个略微作弊的优化,我本着优美的精神没有做过:从技术上讲,此挑战的规则仍然允许为字符串使用不同的输入和输出编码。通过string用其部分应用的Church编码\f -> foldr f [] string :: (a -> [b] -> [b]) -> [b](由函数提供的双向($ (:))射流的另一面)表示任意一个,此编码可降至($ \x->(x:).filter(x/=))24个字符。

我避免将24个字符的响应发布为我的正式响应,因为可以在上述解释器上尝试使用上述解决方案,foldr(\x->(x:).filter(x/=))[]"Type unique chars!"而可以将高尔夫球场解决方案写为:

($ \x->(x:).filter(x/=))$ foldr (\x fn f->f x (fn f)) (const []) "Type unique chars!"

作为更疯狂的文字声明的简写:

($ \x->(x:).filter(x/=))$ \f->f 'T'.($f)$ \f->f 'y'.($f)$ \f->f 'p'.($f)$ \f->f 'e'.($f)$ \f->f ' '.($f)$ \f->f 'u'.($f)$ \f->f 'n'.($f)$ \f->f 'i'.($f)$ \f->f 'q'.($f)$ \f->f 'u'.($f)$ \f->f 'e'.($f)$ \f->f ' '.($f)$ \f->f 'c'.($f)$ \f->f 'h'.($f)$ \f->f 'a'.($f)$ \f->f 'r'.($f)$ \f->f 's'.($f)$ \f->f '!'.($f)$ const[]

但这是表示为纯函数的数据结构的完全有效版本。(当然,您也可以使用\f -> foldr f [] "Type unique chars!",但是这大概是非法的,因为它实际上使用列表来存储数据,因此,它的文件夹部分应该被组成“答案”功能,导致超过24个字符。)

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.