解密源代码[尝试破解的强盗线程]


44

这是“ 解密源代码 ”主要挑战的伴随线程。 如果您认为自己已经弄清了警察的答案之一,则应该发布解决方案作为该主题的答案。

提醒一下,您尝试破解每个提交。您的破解尝试将是源代码的完整版本。如果您的猜测与描述相符(相同的字符,输出以及所用的语言),并且您是第一个正确的猜测,那么您将赢得一分。重要的是要注意,您的程序不必与原始程序完全匹配,只需使用相同的字符并具有相同的功能即可。这意味着可能有多个正确答案。

得分最高(成功破解)的强盗获胜。

排行榜

解决太多

20解决

15解决

10个解决方案

7解决

5解决

4解决

3解决

2解决

1解决


1
Perl 5,尺寸27,由Morot开发 -print'pin'=〜tr(a-za)(za-z)r

@ WumpusQ.Wumbley我们都去过那里;;)
Martin Ender

3
我拒绝浪费时间试图安抚它。

鉴于这两个问题的机构,看来加扰/解扰的答案是相反的
鸣叫鸭

Ruby,MegaTom的23岁 = p%++。methods [80] [1 ..- 1]
历史学家

Answers:


32

CJam,尺寸20,作者:MartinBüttner

Hi "petStorm!", mame

在线尝试。

这个怎么运作

Hi                      "           int(17)                     ";
   "petStorm!",         "                    len('petStorm!')   ";
                ma      "     atan2(       ,                 )  ";
                  me    " exp(                                ) ";
                        " exp(atan2(int(17), len('petStorm!'))) ";

破解代码

所需的输出2.956177636986737为Double或Double,然后为Long。

仅使用中的字符"Stop, Hammer time!",有四个内置运算符可返回非整数Doubles:

  • mS,这是 asin
  • ma,这是 atan2
  • me,这是 exp
  • mt,这是 tan

它们都包含一个m,因此我们最多可以使用其中三个。只有一个S和一个a

所有这些运算符都需要输入,并且ma是唯一消耗两个输入的运算符。我们只有三种方式推长仓:

  • "...",,这会增加字符串的长度(严格小于18)。
  • H,按17。
  • ...!,这将推动逻辑非...

我们无法将虚假的东西推入...,因此最后一个选项将始终推0。

输出不是以17或开头或结尾0。由于15的十进制数字是Double的通常位数,因此输出似乎是简单的Double。

假设这样做,代码必须属于以下类别之一:

  • <Long> <mS|me|mt>{1,3}
  • <Long> <mS|me|mt>{x} <Long> <mS|me|mt>{y} ma <mS|me|mt>{z}
  • 以上任何一项,对Double均进行了一些强制转换为Long(i)或舍入(mo)。

在第二种情况下,x + y + z为1或2,并且Longs之一为0或17。

其余基本上是蛮力。经过几次尝试,

18 , {H \ ma me 2.956177636986737 =} =

返回9,表示

H 9 ma me

产生所需的输出。

剩下的就是从字符串中删除除9个字符以外的所有字符。空间是noops,并且i是Longs上的noop,因此"petStorm!"也是一种可能的选择。


1
太疯狂了-您是怎么知道这个数字的?
Sp3000 2014年

1
我搜索了该数字的对数(及其他),但未得到任何结果。现在我发现我使用的精度太高了。
jimmy23013

2
@ Sp3000:我已经编辑了答案。
丹尼斯

1
非常好!我应该从我猜想的字符串中取出另外两个字符。在我的原著中,我实际上仍然在字符串内留有空格,但是mr在取长度之前是一个空格。并不是说您在某个时候也不会知道。;)
Martin Ender 2014年

25

Python 3,大小12,由xnor

()and bciprt

不执行任何操作(表达式产生一个空的元组,不打印该元组)。这是由于短路评估而起作用的。


1
在Python 3 IDLE中,此输出()
Hosch250

@ hosch250由于它在程序中(Python文件),因此没有任何输出,因为没有print
matsjoyce 2014年

我懂了。我从命令行运行。
Hosch250

47
....“事物” ....
TheDoctor 2014年

4
@Imray由于短路-Python加载元组并检查元组的值是否为true,因为它为空,所以为false。加载变量的代码bciprt永远不会执行,因此永远不会产生NameError。
Mateon1 2014年

20

Python,尺寸74,由xnor

any(print(set is
set)for i in oct(chr is
map))and aeeeeeggiilnnpprrrrrstvw

好吧,那很有趣。感谢FryAmTheEggman,hosch250和isaacg提供的建议/帮助。


1
不错的工作!我的解决方案非常相似:list(\nprint(range is range)for aacdeeeeehmppprrrrssvwy in\noct(int is int))
xnor 2014年

@xnor大声笑那个变量名。我从未想到过这很不好吗?:P
FryAmTheEggman 2014年

2
@FryAmTheEggman我想每个人都希望我使用我的第一任警察的把戏。
xnor 2014年

@FryAmTheEggman别担心,您不是唯一的人:P
Sp3000 2014年


13

GolfScript,尺寸13,彼得·泰勒(Peter Taylor)

,22,{.4&?+.}/

在这里测试。

另外一个,我只有在Sp3000的大力帮助下才能破解。谢谢!

这就是我们到达那里的方式。Sp3000在输出中注意到一连串连续的数字:

1,2,3,4,[2608852181],4582,4583,4584,4585,4586,[253225388392299],
142924,142925,142926,142927,142928,[302928],497409,497409

基于此,我们假设这是一个递增的序列,仅允许对剩余数进行一次可能的拆分:

1,2,3,4,260,885,2181,4582,4583,4584,4585,4586,25322,53883,92299,
142924,142925,142926,142927,142928,302928,497409,497409

那是23个数字,这是重复执行该块22次以及以.(重复的顶部堆栈元素)结束该块的有力指示,这样先前的结果就被留在了堆栈上,并且最终迭代将出现在堆栈两次。那是22,{____.}/

现在看一下差距,结果发现它们是四次方(这很不错,因为我们有4and ?)。更准确地说,它们是当前数字索引的四次方。接下来,我们看看哪些指数造成了差距:

4,5,6,7, 12,13,14,15, 20,21,..?

用二进制的是

00100
00101
00110
00111
01100
01101
01110
01111
10100
10101

它们都设置了第三个位,这意味着索引可能只是按位加和的4(这很好,因为我们可以4.和制作另一个&)。这特别好用,因为此运算的结果为04,如果我们将其用作指数,则将获得1或四次幂,这正是我们所需要的。因此,我们将其放在一起:

22,{.4&?+.}/

这是该块的作用:

.      # Duplicate current index
 4     # Push a 4
  &    # Bitwise and
   ?   # Raise index to resulting power
    +  # Add to previous result
     . # Duplicate for use in next iteration

现在剩下两个问题:我们有一个,尚未使用的流浪,并且第一次迭代是一个特例,因为先前的迭代没有任何价值,我们遇到时可以添加一些东西+。我们发现,感谢user23013的不相关评论,他不经意地提到GolfScript从堆栈上的空字符串开始(如果STDIN上没有任何内容)。因此,我们可以,在开始时使用其他权利将字符串转换为0,这正是迭代开始时所需要的。


发现。这是受OEIS中序列的启发,我现在找不到。
彼得·泰勒

3
这就是为什么为强盗设置单独的线程是一个好主意的原因。不错的工作!
丹尼斯



11

PHP,大小49,由bwoebi

print@substr(new exception,+~$$a+=++$$m+$$i+2+n);

那绝对是精神上的

到了

print@substr(new exception,);

很快,这时我需要-6用逗号隔开后$++$++$++$+=$~main$2离开的东西。

主要的收获是$a$mand $iare all NULL,因此在变量变量中间接使用它们意味着它们都指向同一个变量。但是,PHP似乎在解决变量变量方面做了一些奇怪的事情。使用普通变量,您可以执行以下操作

echo $a+$a=2;

打印4(将2其分配给自己$a,然后添加到其自身)。但是如果我对变量变量做同样的事情:

echo $$a+$$a=2;

我得到了2,因为现在第一个$$a是赋值之前的评估。

最后,我设法通过在RHS上增加一些RHS来强加一些命令,在增加+=分配之前必须对其进行评估。这样5,我就可以进行位补码。仍然...发生了一些神秘的事情,我不知道为什么我尝试的一半事情起作用了而没有起作用。


作为参考,我的原文:print@substr(new exception,~$$mn+=2+$$a+++$$i++);
bwoebi 2014年

顺便说一句。我希望所有的美元符号以及main该字符串中所有字母都误导您的事实。另外,{main}我认为这是一种非常不寻常的提取方法;-)
bwoebi 2014年

@bwoebi的main并没有真正误导我,点样后exceptionnewsubstr。我以为它们只是变量名。我花了一些时间才想出使用可变变量的方法,然后我花了大部分时间弄清楚一些运算顺序,这些运算顺序实际上会产生一个5我可以在不使用另一组括号的情况下进行补充的运算。
2014年

好吧,下一次,如果美元多于字符,通常是可变变量。(在这种情况下,我还滥用了varvars来强制执行从左到右的评估。)然后,您花了多长时间才能发现substr新异常?顺便说一句,我对Zend引擎有更深入的了解,因此我可以向自己完美地解释为什么要按什么顺序对事物进行评估,而这对于这些挑战是很好的;-)如果有您不了解的特定事物,我会很高兴向您解释。
bwoebi 2014年

@bwoebi 明天聊天,我们可以讨论这个问题,但是我今天已经花了很长时间。;)关于你的第一个问题,exception是显而易见的,它留给流浪字符substrnew躺在身边。从字面上看,这是我开始进行这项工作时看到的第一件事。
Martin Ender 2014年

9

红宝石,尺寸38,由Doorknob设计

[$><<(!$pece60).to_s[rand($win)].succ]

我很确定这与原始来源相去甚远。尽管使用,它还是确定性的rand

这是这样的工作方式。$><<只是输出。$pece60并且$win是未定义的全局变量,因此是公正的nil(它们使我摆脱了一些多余的字符)。!$pece60制作一个trueto_s给出字符串"true"

很长一段时间以来,我都尝试在其中获取2-2访问它u,但是后来我意识到我可以带上t,然后调用.succ(essor)创建一个u

rand 与一个 nil参数的参数将返回间隔[0,1)中的随机浮点数。当使用浮点数将其索引为字符串时,它们会被截断为整数,因此它将始终返回第一个字符。

最后,我有一对备用 []所以我把所有东西都包裹了,因为值得庆幸的是,所有东西都是Ruby中的表达式。

感谢Sp3000在聊天中提出一些想法。


8
Ruby是一种令人恐惧的语言。
feersum 2014年

8

C,51由es1024

c=0xf.cp9,hhtaglfor;main() {;; printf("%d",(++c));}

经过20年的C语言编程,今天我了解了十六进制浮点常量。


8

Ruby,45岁(历史学家)

%q[zyfnhvjkwudebgmaclprs x].to_i(36)/51074892

hoo!这是我第一次解决代码高尔夫球问题,并且我没有足够的代表来评论原始帖子。我立即意识到所使用的技巧,因为我经常在生产代码中发现它的用途。大约花了5分钟才能弄清大部分结构,花了几个小时才能得出完整的答案。

说明:

  • %q[]是创建字符串的另一种方法。也可以使用括号和花括号。
  • String#to_i Ruby中的int接受2到36之间任何数字的基数。它将忽略字符串中不属于数字的第一个字符,因此可以在空格后“扔掉”任何多余的字符。

这是我用来破解它的代码:

require 'set'

# return true if the string is made up of unique characters
def uniq(s)
  a = s.each_char.to_a
  return a == a.uniq
end

def uniq_while_same(a,b)
  s = Set.new
  a.each_char.zip(b.each_char).each do |ai, bi|
    return true if ai != bi
    return false if s.include? ai
    s << ai
  end
  return true
end

def ungolf(answer)
  # For each base that even makes sense
  [            36, 35, 34,     32, 31, 30,
   29, 28, 27, 26, 25, 24, 23,     21, 20,
   19, 18, 17, 16, 15, 14, 13, 12,     10].each do |base|
    # Ignore bases where it is not possible to create a unique-string number greater than answer
    next if answer > base ** base
    # Pick digits for the denominator that are not duplicates of the digits in base
    denominator_digits = ('1234567890'.each_char.to_a - base.to_s.each_char.to_a)
    # For each permutation of those digits for the denominator
    (1..10).each do |denominator_length|
      denominator_digits.permutation(denominator_length) do |denominator_s|
        # Maybe the denominator is in octal
        denominator_base = 10
        if denominator_s[0] == '0'
          next if denominator_s.include?('8') || denominator_s.include?('9')
          denominator_base = 8
        end
        denominator_s = denominator_s.join
        denominator = denominator_s.to_i denominator_base
        print "#{"\b"*64}(%q[#{(answer * denominator).to_s(base).ljust(36)}].to_i #{base})/#{denominator_s.ljust(10)}" if rand < 0.01
        # Ignore denominators that are definitely impossible to have answers for
        next unless uniq_while_same "qtoi#{base}#{denominator_s}#{(answer * denominator).to_s(base)}",
                                    "qtoi#{base}#{denominator_s}#{((answer + 1) * denominator).to_s(base)}"

        # For each numerator that gives answer when divided by the denominator
        (answer * denominator...(answer + 1) * denominator).each do |numerator|
          print "#{"\b"*64}%q[#{numerator.to_s(base).ljust(36)}].to_i(#{base})/#{denominator_s.ljust(10)}" if rand < 0.01
          # Remove any that are still not unique
          s = "#{numerator.to_s(base)}#{base}#{denominator_s}qtoi"
          next unless uniq s
          # Done. Compute which characters need to be thrown away to fill the remaining space
          remains = ('0123456789abcdefghijklmnopqrstuvwxyz'.each_char.to_a - s.each_char.to_a).join
          print "#{"\b"*64}#{" "*64}#{"\b"*64}"
          return "%q[#{numerator.to_s(base)} #{remains}].to_i(#{base})/#{denominator_s}"
        end
      end
    end
  end
  print "#{"\b"*64}"
  puts "\nnone"
  return nil
end


print ungolf 9410663329978946297999932

将NP问题嵌入谜语的方法。我被书呆子彻底透了。做得好!


我为您的原始答案添加了评论。
FireFly 2014年

这很棒(并且接近预期的答案),但是在技术上无效,因为它没有输出。
histocrat 2014年

* facepalm好吧,我仍然很开心。
charredUtensil 2014年

2
@charredUtensil如果您不介意再运行脚本,我认为打印只是将p表达式移动到表达式之前。大概剩余的字符可以用来构成常量。
FireFly 2014年

我实际上不需要再次运行它。可以在不更改结果的情况下重新排列字符串的最后几个字符- p %q[zyfnhvjkwudebgmaclrsx].to_i(36)/51074892我知道我虽然打破了实际的破解尝试:)
charredUtensil 2014年



7

CJam,尺寸13,按用户23013

G,Cf#If/sE*K%

在这里测试。

手工解决,像这样:

首先,非CJammers的一些背景:

  • CEGIK都是变量,这些变量预先初始化为1214161820,分别。
  • s 将顶部堆栈元素转换为字符串。
  • 从技术上讲,字符串只是字符数组。
  • f真是神奇。出于此答案的目的,简化版本是:对于数组a,一些其他值b和一个运算符g,该序列abfg映射g(_,b)a(其中的每个元素a进入_插槽的位置)。
  • / 是除法和分裂数组(除其他外)。
  • * 是乘法和数组重复(以及其他)。
  • %是取模和一些奇怪的操作,ad%以数组a和整数的形式d占用d元素的每一个元素a(例如Python用步长进行切片d)。
  • # 是幂(除其他外)。
  • ,将数字变成范围(从0n-1),并返回数组的长度。

好吧,顺便说一下...

显然,我们需要,将数字转换为范围,因为获取数组的唯一另一种方法是构建一个更大的数字,并使用s- 将其转换为字符数组,但随后我们什么也做不了对其进行进一步的运算。我们需要一个数组来对f s进行操作。

我首先假定fs与#和一起使用%,但这意味着我们需要大约90的数字才能最终获得正确的数字。而且,这也不能解释该怎么做s,并且由于答案看起来像高尔夫球一样,我怀疑user23013只是s在某处附加了有效的无操作性,以致使人们无法工作。

所以我想,也许他甚至都没有将数字保持很小%,而是他建立了一个庞大的数字数组,将它们的字符串表示形式连接在一起s,但随后只从中选择了一些奇数%。因此,我在以下框架上做了一些尝试:

__*,_f#_f/s_%

(您不能_f/先执行此操作,因为至少前12个元素会产生零。)

哪里_是变量的一些排列。在感到无聊之前,我并没有尝试所有的方法,主要的问题是数字序列总是太长。

在某种程度上,我想到,我们不需要这么大的范围(即两个数字的乘积),而是使用*来重复生成的字符串。由于参数的不匹配*%这将产生的结果,不重复:

_,_f#_f/s_*_%

这样产生的结果长度非常接近我想要的长度。我实际上会尝试所有240个,但是很快(第三次或第四次尝试),我偶然发现

E,Cf#If/sG*K%

产生

03081942753650251594592190492275006661328850322159030034930530649722385533653290754678977

而且我认为前六位数字的匹配不是巧合。所以问题是如何在不影响实际计算的情况下重新排列它:

  • 我无法更改,K因为这将完全挑选出不同的数字。
  • 我无法更改,C或者I因为那样会更改两次映射操作产生的数字。
  • 如果我改变了G,那只会改变重复的次数,只会改变结果的长度。(哪个好)
  • 如果我进行了更改E,则会更改数组的范围,但范围仍以开头[0 1 2 3 ...],因此不会影响计算。这影响所返回的基本字符串的长度s,这也意味着K%在进行额外的重复操作后会选择不同的数字。

所以,我只是想交换EG瞧:

030819828850379075460427536222159187897761502517030034671154875945928930530907551421904962649729

总之,这是代码的作用:

G,            "Push [0 1 2 3 ... 13 14 15].";
  Cf#         "Raise each element to the 12th power.";
     If/      "Divide each element by 18.";
        s     "Concatenate all numbers into a string.";
         E*   "Repeat 14 times.";
           K% "Pick every 20th digit.";


6

Pyth,尺寸11,由isaacg

:\\w$ ",d,N

那就是那里的一些平均错误滥用。编译为:

Pprint("\n",at_slice("\",input(), ",d,N))

相关的错误是\\编译为"\"而不是"\\",它使您可以将Pyth编译为字符串。


应该Pprintprint,或者至少是pprint
FireFly 2014年

@FireFly这就是调试输出说明的内容。也许Pyth解释器定义了自己的Pprint?
Martin Ender

哦,好的,没关系。
FireFly 2014年

6

Python,尺寸69,按Sp3000

print(sum(list(map(ord,str((dict(((str(dict()),list()),)),str()))))))

那很难...


1
真好!供参考,原文为print(sum(map(ord,str((dict(list(((str(),str(dict())),))),list()))))),但显然可以使用许多不同的关键字排列方式。
Sp3000 2014年

2
那就是LISP级别的parens!
xnor 2014年

6

Python 3,37字节,Sp3000

print(sum(b"a".zfill(len(str(...)))))

令人尴尬的是,到目前为止,最困难的部分是想办法将字符串转换为字节。我不得不在上面睡觉,到了晚上,我才意识到:“啊,这真是个字节!”


阿哈哈做得很好,我以为Ellipsis可能会使人绊倒,但我想不是
Sp3000

我看到了省略号和zfill,但不了解bytes对象。这些可能对整数数组打高尔夫球很有用!
feersum 2014年

很好!我只看到打印和.zfill,我知道sum可能是其中的一部分,但我无法解决。+1。
Hosch250 2014年

6

PHP,53,由PleaseStand

最后破解了:

for($d=57,$o=35;$o+$d<999;)$o+=printf("$d%o",$d+=$o);

当我注意到序列由十进制和八进制数字组成时,解决方案很快就来了:

Dec: 57...92...132...177...228...285...348...417...492....573....661....756....858....
     571349220413226117734422843528553434864141775449210755731225661136475615328581707
Oct: ..134..204...261...344...435...534...641...754...1075...1225...1364...1532...1707
==Dec:  92  132   177   228   285   348   417   492    573    661    756    858    967

同样,每组数字之间的间隔以等于返回值printf()(即,写入的字符数)的速率增长。


3
哇,好侦探!
Sp3000

6

Python 2,尺寸132,由Vi提供。

exec('from string import printable as e\nprint "cqance"\x2Ereplace("q",e[len("fgiillmmooprrsstt")])or ",,,\016:::S[]____tuuvyy" ""')

感谢所有的反斜杠和引号:)


编辑:更新的96字符版本:

exec "try:exec'from __future__ import braces\\nt(12)'\nexcept SyntaxError as q:print(q[0][6:])"

这完全取自https://codegolf.stackexchange.com/a/41451/32353的 Alex解决方案


嘿,很好。想知道什么是理想的解决方案……
FireFly

这不是预期的解决方案。原来的解决方案没有任何“用完即弃”之类的东西fgiillmmooprrsstt,,,\016:::S[]____tuuvyy
六。

exec?我的代码本来应该更短一些……我用compile+来模拟它,eval因为我忘记了exec……
Vi。

实现了较短的版本。尝试找出原始的把戏。
六。

5

CJam,尺寸15,由Ypnypn

98,{7%}%{6+}%:+

从给定的字符,我猜想它必须是以下三种形式之一:

__,{_%}%{_+}%:+
_,{_%}%{__+}%:+
__,{_+}%{_%}%:+

它会创建一个两位数的范围,然后将加法和取模运算(以任意顺序)映射到该范围,然后再求和。因此,我只是从第一个开始,并系统地尝试6789了间隙的排列。


该死,我也刚解决了它:/
Optimizer


5

Python 2,大小61,由FryAmTheEggman提供

print(dir('~s]l.c:st_''-p_tp.l]-~.:o:Te[_u[.i_')[10][2:][:3])

如果这与原著相符,我会感到非常惊讶。


不会,但是无论如何都要恭喜!我的代码是:print''.__doc__[::2][::3].split()[1].split('.')[0][:-~-~True]
FryAmTheEggman,2014年

事后看来,我不应该加上引号...;)
FryAmTheEggman 2014年

@FryAmTheEggman哇-好程序!我确信您至少已经习惯dir()了找到“获取”的方法。是的,如果没有引号,那将是非常困难的。
grc 2014年

5

Python 3,Sp3000,尺寸44

print(~(~(()<((),))<<(()<((),))))<<((()<()))

Python 3在这里为我提供了帮助,因为None在打印答案后,我能够导致错误(左移某些东西)。


嗯...我的父母似乎很浪费。有print(~(~(()<())<<((()<((),))<<(()<((),)))))原本。
Sp3000 2014年

5

PHP,大小52,由kenorb

_:@print_r(chr(@++$i+pow(3<<5,1)));if($i<2*4)goto _;

(上帝,我花了多长时间才知道如何处理剩余的_r后缀。直到我注意到不是print,而是print_r...)


而且我不知道您是怎么知道的:)原始资料:_:print_r(chr(3*pow(2,5)+@++$i));if(@$i<4<<1)goto _;
kenorb 2014年

3
@kenorb a)您需要打印一些东西,所以echo不可能;print仍然; b)您需要一些循环,但是对于for循环来说,分号不够,而且,还有一个冒号……所以可能在其中加上了goto的标签;c)那么是否需要中止goto循环。现在拥有X:print($Y);if($Y)goto X;(X和Y为占位符);d)有一个++,但没有=,所以大概是++$Z1到8;e)要从整数获取字母,我们需要chr()(通常)-它在那里;f)现在我只需要找到chr和if的数字96和8。然后填写占位符和volià。
bwoebi 2014年


5

C,es1024,长度70

e='C',f;main(g){Chorkil:f=printf("40%.d",e+e-  -g);}hAx;*hotpoCkats();

困难的部分最终是要跟踪所有不需要的字符……严重……我不得不将它们重做大约10次。唯一让我担心的是,.但是我以某种方式将其粘贴在printf格式字符串的中间,它变得不可见!



5

Haskell,34号,作者PetrPudlák

main=print(0xb2f3d5^0x7f1f27::Int)

请注意,该程序必须在32位计算机上运行。如果要检查这是正确的程序,并且拥有64位计算机,则可以改用以下程序:

import Data.Int
main=print(0xb2f3d5^0x7f1f27::Int32)

很容易猜出程序的“框架” main=print(0x<hex digits>^0x<hex digits>::Int)。所有的魔力在于寻找正确的方法来分割和排序数字。在这里,我并没有做很多聪明的事情,只是蛮力搜索了……虽然我确实小心翼翼地滥用了一些数字重复的事实,但底数和指数中可能有相等数目的数字,并且基数的最后一位几乎没有。完整的搜索代码如下。它使用multiset-comb软件包。完整搜索在我的机器上花费大约10:33(当然,仅产生一个正确答案)。

{-# LANGUAGE NoMonomorphismRestriction #-}
import Control.Monad
import Data.Int
import Data.List (inits, tails, group)
import Numeric
import Math.Combinatorics.Multiset

main = print (searchFor (-1121766947))

searchFor n = do
    nl <- [6,5,7,4,8,3,9,2,10,1,11]
    (l_, r_)  <- chooseSubbag nl digits
    l <- perms l_
    guard (last l /= '2')
    r <- perms r_
    guard ((fromString l :: Int32) ^ (fromString r :: Integer) == n)
    return (l, r)

chooseSubbag n = chooseSubbag' n . group
chooseSubbag' n xss = go (drop (n-1) (concat xss)) n xss where
    go _  n xss | n < 0 = []
    go _  0 xss = [([],concat xss)]
    go [] n xss = []
    go m  n (xs:xss) = do
        (kx, tx) <- zip (tails xs) (inits xs)
        (k , t ) <- go (drop (length tx) m) (n-length kx) xss
        return (kx++k, tx++t)

digits = "1223577bdfff"
fromString = fst . head . readHex
perms = permutations . fromList

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.