互换指数和价值


29

任务

编写一个程序或函数,其输入是整数的列表/数组X,输出是整数Y的列表,这样对于每个集合Y中的每个元素e [ i ],X [ e ] = i和这样,Y中集合中元素的总数等于X中元素的数目。

(除了应用于数组之外,这基本上与反转哈希表/字典相同。)

例子

这些示例假定基于1的索引,但是如果愿意,可以改用基于0的索引。

X             Y
[4]           [{},{},{},{1}]
[1,2,3]       [{1},{2},{3}]
[2,2,2]       [{},{1,2,3}]
[5,5,6,6]     [{},{},{},{},{1,2},{3,4}]
[6,6,5,5]     [{},{},{},{},{3,4},{1,2}]

澄清说明

  • 如果愿意,可以将一个集合表示为一个列表。如果这样做,其元素的顺序无关紧要,但是您可能不会重复元素。
  • 您可以使用任何合理的明确I / O格式;例如,您可以用空格分隔集合的元素,并用换行符分隔集合本身。
  • Y应该是有限长的,并且至少要长到足以将X的所有元素都作为数组索引。但是,它可能比X的最大元素长(多余的元素将是空集)。
  • X的元素都将是有效的数组索引,即,如果使用基于0的索引,则为非负整数;如果使用基于1的索引,则为正整数。

胜利条件

作为挑战,越短越好。


相关的。在“ 沙箱”帖子(现已删除,但是如果您有声誉,则可以查看)中,我们认为它可能不是重复的,但是如果您不同意,可以随意投票关闭。

难道“其元素的顺序并不重要,”意味着的输出[5,5,6,6],并[6,6,5,5]可以是相同的?
Leaky Nun

1
@LeakyNun输出列表中集合元素的顺序无关紧要。因此[5,5,6,6][6,6,5,5]不能有相同的输出,但是的输出[5,5,6,6]也可以是,例如[{},{},{},{},{2,1},{4,3}]
ngenisis

X中是否存在索引的可估计最大值?空集也可以在其中包含0而不是实际上是空的吗?例如,[{0},{0},{0},{0},{1,2},{3,4}]对于[5,5,6,6]
Skidsdev

@Mayube:否定第一个答案(尽管如果您使用整数范围有限的语言,则可以编写程序,就好像整数可能会无穷大一样,如果有人给您超出范围,您不必担心它会中断,范围整数作为输入)。关于第二个问题,当您使用基于1的索引时,这是明确的(如果很奇怪)语法,因此在这种情况下是(显然,如果您使用基于0的索引,则为否,因为那样的话0意味着某种意义其他。)

Answers:


9

MATL,8字节

tn:IXQ&D

输入是带有;分隔符的列向量(例如[2;2;2])。输出是行向量的单元格数组的字符串表示形式(例如{[]; [1 2 3]})。单个元素的行向量与数字相同(因此{1; 2; 3}将输出而不是{[1]; [2]; [3]})。

在线尝试!验证所有测试用例

说明

t     % Implicit input, say x. Duplicate
n     % Number of elements, say N
:     % Range: [1 2 ... N]
IXQ   % accumarray(x, [1 2 ... N], [], @(x){sort(x).'})
&D    % String representation

Matlab的高阶函数完成了大部分工作accumarray,该函数根据第一个输入中的匹配值将第二个输入中的元素分组,然后将指定的函数应用于每个组。在这种情况下@(x){sort(x).'},该函数是,该函数输出每个组中排序的元素,并使所有组的结果打包在一个单元格数组中。


7

Python,69个字节

lambda s:[[j for j,x in enumerate(s)if x==i]for i in range(max(s)+1)]

使用基于0的索引。


7

果冻7 5字节

=þṀT€

在线尝试!

怎么运行的

=þṀT€  Main link. Argument: A (array)

  Ṁ    Yield m, the maximum of A.
=þ     Equals table; for each t in [1, ..., m], compare all elemnts of A with t,
       yielding a 2D Boolean array.
   T€  Truth each; for each Boolean array, yield all indices of 1.

5

果冻,8字节

Jẋ"Ṭ€;"/

在线尝试!

怎么运行的

Jẋ"Ṭ€;"/  argument: z           eg. [6,6,4,4]
J         [1 .. len(z)]             [1,2,3,4]
   Ṭ€     untruth each of z         [[0,0,0,0,0,1],
                                     [0,0,0,0,0,1],
                                     [0,0,0,1],
                                     [0,0,0,1]]
 ẋ"       repeat each of ^^         [[[],[],[],[],[],[1]],
          as many times as           [[],[],[],[],[],[2]],
          each of ^                  [[],[],[],[3]],
                                     [[],[],[],[4]]]
       /  reduce by...
     ;"   vectorized concatenation  [[],[],[],[3,4],[],[1,2]]

4

Mathematica,36个字节

Join@@@#~Position~n~Table~{n,Max@#}&

说明

enter image description here

对于nin中{1, 2, ..., Max@#},where Max@#是输入列表中最大的整数,计算Positions n出现在输入列表中的#。由于Position[{6,6,5,5},5](例如)返回{{3},{4}},因此我们将结果返回Apply Join到所有元素{1}


3

Haskell,45个字节

s接受一个整数列表并返回一个列表列表。1索引,以保持测试用例的输入不变(尽管输出得到一些额外的空列表)。

s l=[[i|(i,y)<-zip[1..]l,y==x]|x<-[1..sum l]]

在线尝试!

这些是非常简单的嵌套列表推导。唯一的调整是利用选项sum而不是来制作更长的列表maximum


3

PHP,55字节

<?while($i<=max($_GET))print_r(array_keys($_GET,$i++));

0索引。


3

R,68 49 47字节

lapply(1:max(x<-scan()),function(y)which(y==x)) 

令人惊讶的是,比更长的解决方案简单得多。x从STDIN中获取一个向量,从1to中创建一个向量max(x),隐式生成一个length列表max(x),并检查其中的索引x与新列表中的索引相对应。隐式打印输出。

旧版本:

o=vector('list',max(x<-scan()));for(i in x)o[[i]]=c(o[[i]],F<-F+1);o

其他R答案的方法略有不同。将向量带到STDIN,创建一个列表,该列表的长度等于输入中的最大值。循环输入,并将索引添加到正确的位置。

使用基于1的索引。


2

Python 2中91 86 85个字节

我正在用手机编程,但我真的很喜欢这个挑战。我绝对可以进一步打高尔夫球。

def f(a):
 r=[[]for i in range(max(a)+1)]
 for i,j in enumerate(a):r[j]+=[i]
 print r

在线尝试!


嵌套列表理解再次使人迷路。:D
完全人类的,

2

果冻,9 字节

Ṭ+\ịĠȧ@"Ṭ

1个索引的空集,表示为0,一个项目的集表示为,N多个项目的集表示为[M,N,...]

在线尝试!

怎么样?

Ṭ+\ịĠȧ@"Ṭ - Main link: list a        e.g. [6,6,4,4]
Ṭ         - untruth a                     [0,0,0,1,0,1]
  \       - cumulative reduce with:
 +        -   addition                    [0,0,0,1,1,2]
    Ġ     - group indices of a by value   [[3,4],[1,2]]
   ị      - index into                    [[1,2],[1,2],[1,2],[3,4],[3,4],[1,2]]
        Ṭ - untruth a                     [0,0,0,1,0,1]
       "  - zip with:
     ȧ@   -   and with reversed @rguments [0,0,0,[3,4],0,[1,2]]

2

JavaScript(ES6),64 62字节

@SteveBennett节省了2个字节


接受0索引输入。返回以逗号分隔的集合列表。

a=>a.map((n,i)=>o[n]=[i,...o[n]||[]],o=[])&&`{${o.join`},{`}}`

测试用例


替代版本,53字节

如果'||||3,2|1,0'可以接受一个简化的输出,我们可以这样做:

a=>a.map((n,i)=>o[n]=[i,...o[n]||[]],o=[])&&o.join`|`

哇。我很困惑`{${o.join`},{`}}`ES2015 如何合法。
史蒂夫·贝内特

@SteveBennett,它是模板文字。在旧版本的JS中"{" + o.join("},{") + "}",如果这样可以使它更清晰,则为。
毛茸茸的

不,我知道这些-加入这个词后的反引号使我感到困惑。是关闭字符串(在这种情况下为wtf),还是逃脱右括号?
史蒂夫·本内特

嗯,好的,因此在这种情况下join`等同于join('。不知道你能做到这一点。
史蒂夫·本内特

啊,现在我明白了。这是一个带标签的模板文字。你可以滥用节省几个字符时调用的函数,它有一个字符串参数(而忽略其他人): array.join` `。这里超级混乱,因为您将其嵌入模板字符串中,更令人困惑的是},{,连接字符串是,巧合地看起来像模板字符串的一部分……反正又奇怪又丑陋。:)
史蒂夫·贝内特


1

Mathematica 62字节

(Y={}~Table~Max@#;Y[[#[[j]]]]~AppendTo~j~Table~{j,Tr[1^#]};Y)&

我帮你办

(Y={}~Table~Max@#;Y[[#[[j]]]]~AppendTo~j~Table~{j,Tr[1^#]};Y)&[{4,5,2,3,3,8,6,3}]

{{},{3},{4、5、8},{1},{2},{7},{},{6}}

在线尝试(只需使用ctrl-v粘贴代码,然后按shift + enter键)
别忘了像上面的示例一样在最后粘贴输入列表


欢迎来到PPCG!您可以使用中缀符号来保存一个字节AppendTo。另外,{j,1,Length[#1]}可能只是{j,Length@#},甚至更短{j,Tr[1^#]}Tr[1^#]是使用节省一个字节的常见技巧Length
ngenisis

1

Perl 6的 36 32  29个字节

->\a{map {a.grep(*==$_):k},1..a.max}

试试吧

{map {.grep(*==$^a):k},1.. .max}

试试吧

{map {.grep($^a):k},1.. .max}

试试吧


展开:

{  # bare block lambda with implicit parameter 「$_」

  map

    {  # bare block lambda with placeholder parameter 「$a」

      .grep(  # grep for the values in 「$_」
        $^a   # that are equal to the currently tested value (and declare param)
      ) :k    # return the key (index) rather than the value
    },

    1 .. .max # Range from 1 to the maximum value in 「$_」

}

返回基于零的索引,以使用交叉运算符(X)与+op 相结合来获得基于1的索引。(33字节)

{1 X+.grep($^a):k}

要使其返回Set,只需在其中添加set(总共37个字节)

{set 1 X+.grep($^a):k}

1

R,80 72字节

1索引,X取自stdin。返回索引的向量列表,NULL以其为空集。

X=scan();Y=vector('list',max(X));Y[X]=lapply(X,function(x)which(X==x));Y

在线尝试!

旧版:

X=scan();Y=vector('list',max(X));for(i in 1:length(X))Y[[X[i]]]=c(Y[[X[i]]],i);Y

在线尝试!


我认为Y=list();效果也不错
rturnbull

设法few在我的答案中删除
JAD


0

Röda,51个字节

f s{seq(1,max(s))|[[s()|enum|[_2+1]if[_1=i]]]for i}

这是UrielPython答案的移植。

另一个版本(88字节):

f a{I=indexOf;seq(1,max(a))|{|i|b=a[:]c=[]x=1{c+=x+I(i,b)b-=i;x++}until[I(i,b)<0];[c]}_}

在线尝试!

两者均为1索引。



0

GNU制作214个 213 208 204字节

X=$(MAKECMDGOALS)
M=0
P=$(eval N=$(word $1,$X))$(if $N,$(if $(shell dc -e$Nd$Mds.\>.p),$(eval M=$N),)$(eval A$N+=$1$(call $0,$(shell expr $1 + 1))),)
$(call P,1)$(foreach K,$(shell seq $M),$(info $(A$K)))

I / O:通过参数输入数组,输出到stdout,每行一个,以空格分隔。

$ make -f swap.mk 2 2 2

3 2 1
make: *** No rule to make target `2'.  Stop.

说明

X=$(MAKECMDGOALS)     # Input array
M=0                   # Max value encountered in X
P=$(eval
    N=$(word $1,$X))  # Get next word from X
  $(if $N,$(if $(shell dc -e$Nd$Mds.\>.p),
    $(eval M=$N),)    # Update M
    $(eval A$N+=$1    # Append index to a variable named after value
      $(call $0,      # Recurse (call returns empty string)
        $(shell expr $1 + 1))),)
$(call P,1)           # Initial call to P. 1 is the first index
$(foreach K,          # Print all values of A* variables
  $(shell seq $M),
  $(info $(A$K)))     # Uninitialized ones default to empty strings

集合中索引的顺序相反,因为P在更新之前递归调用自身A$2(在右侧评估中执行调用)。


请问make有什么办法做算术本身?调用外部程序来执行此操作感觉有点像作弊,因为您可能会将更多算法放到这些程序中,最终得到一个较短的程序。

@ ais523还没有。以前的版本使用bcgrep。我也可以使用test$?dc具有简短的语法,但坦率地说,所有这些都感觉相同。
eush77

0

Common Lisp,91个字节

(lambda(x &aux(l(make-list(eval`(max,@x))))(i 0))(dolist(y x l)(push(incf i)(nth(1- y)l))))

从1开始的索引,将集合作为列表返回。

在线尝试!


0

k,13个字节

{(=x)@!1+|/x}

这是0索引。

在线尝试!

{           } /function(x)
 (=x)         /make a map/dictionary of values to their indices
         |/x  /get maximum value in x
      !1+     /make a range from 0 to the value, inclusive
     @        /get map value at each of the values in the range
              /    0N is given where there is no result
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.