整数,集合!


30

您的任务是将从1到的整数N(作为输入)组装成一个具有宽度W和高度的矩形H(也作为输入提供)。单个数字可以旋转90度的任意倍数,但是它们必须在矩形中显示为连续的块。也就是说,您不能将其中一个数字分解为多个数字并将这些数字分别放置在矩形中,也不能将数字的三个数字弯曲到一个角上。您可以考虑每个数字都是用来建造墙的砖头。

这是一个例子。说您的输入是(N, W, H) = (12, 5, 3)。一种可能的解决方案是:

18627
21901
53114

为了清楚起见,这里有此网格的两个副本,一个副本隐藏了一位数字,而另一个副本隐藏了两位数字:

1####    #8627
2##01    #19##
##11#    53##4

如果矩形不能以独特的方式再次拆卸,那就很好。例如,在上面的示例中,12也可以这样放置:

#####    18627
21#01    ##9##
##11#    53##4

规则

您可以假定它N是正W*H数,并且与整数从1N包含在内的位数匹配,并且存在将矩形平铺到给定数字中的情况。我目前尚无证据证明这是否总是可能的,但是如果您愿意,我会对此感兴趣。

输出可以是单个换行符分隔的字符串,也可以是字符串列表(每行一个),也可以是一位整数列表的列表(每个单元格一个)。

提交的结果必须是确定的,并且您应该能够在合理的台式机上在一分钟之内处理所有测试用例。

您可以编写程序或函数,并使用我们的任何标准方法来接收输入和提供输出。

您可以使用任何编程语言,但是请注意,默认情况下,这些漏洞是禁止的。

这是,因此以字节为单位的最短有效答案为准。

测试用例

除了第一个,这些都不是唯一的。每个测试用例N W H后面都有一个可能的输出。当矩形太窄而无法水平书写较大的数字时,请确保您的答案有效。

1 1 1
1

6 6 1
536142

6 2 3
16
25
34

10 1 11
1
0
8
9
2
6
7
3
1
5
4

11 13 1
1234567891011

27 9 5
213112117
192422581
144136119
082512671
205263272

183 21 21
183116214112099785736
182516114011998775635
181116013911897765534
180415913811796755433
179115813711695745332
178315713611594735231
177115613511493725130
176215513411392715029
175115413311291704928
174115313211190694827
173115213111089684726
172015113010988674625
171915012910887664524
170814912810786654423
169714812710685644322
168614712610584634221
167514612510483624120
166414512410382614019
165314412310281603918
164214312210180593817
163114212110079583716

200 41 12
81711132917193661114105533118936111184136
50592924448815915414562967609909953662491
89529721161671582389717813151113658811817
41418184511110119010183423720433017331118
35171183614003547461181197275184300111711
41874381132041861871718311415915921116264
11914245014112711011594492626831219331845
17125112629222085166344707736090956375181
94507611291431121128817413566319161275711
11011540021119913511011169939551729880780
92725141607727665632702567369893534277304
78118311405621148296417218591118562161856

8
有证据证明这总是可能的吗?
致命

@Fatalize实际上是个好问题。您可以假设所有给定的输入都可以使用,但是无论哪种方式的证明都将很有趣。
Martin Ender

@Fatalize:至少在平凡的input情况下(10, 1, 1),这是不可能的(假设N构造中必须使用从1到MUST的所有数字)。如果保持该约束,则矩形区域的单位必须至少为位数,1..N以使其成为可能。如果放宽约束,那么在所有情况下都有可能(但是挑战并不那么有趣:P)
塞巴斯蒂安·莱纳托维奇

2
@SebastianLenartowicz:我想您错过了说矩形区域与[1,N]中数字的总和相匹配的部分。如果N == 10,则宽度和高度必须为1和11。如果宽度或高度为1,则始终可以解决此问题。
Yay295 '16

1
@MartinEnder相反的挑战也可能很有趣:输入数字N的矩形(最终是,但程序可以从宽度和高度计算出来),并且程序需要检查矩形是否是对此挑战的有效答案。 ...
达达

Answers:


3

Pyth,35个字节

juum+WghHl+dQd~tQN<+.TGmkeHeH)_BvzY

致谢mbomb007。我用他的算法。最初,我只想帮助Steven H.,但后来我真的想看一个简短的版本。

注意到N在第一行,并W,H在第二行:在线试玩:示范

在Pyth实施中发现了一个令人讨厌的错误.[(我自己的错,因为我实施了它)。明天要修复。这导致了+3个字节。

说明:

juum+WghHl+dQd~tQN<+.TGmkeHeH)_BvzY
                                  Y   start with the empty list []
                                      I'll perform all operations on this list. 
                                      Sometimes it is called G, sometimes N. 
                                vz    read the second line and evaluate it: [W, H]
                              _B      bifurcate it with reverse: [[W, H], [H, W]]
 u                                    for each pair H in ^:
                    .TG                  transpose G
                   +   mkeH              append H[1] empty strings
                  <        eH            use only the first H[1] strings
                                         lets call this result N
  u                          )           modify N, until it doesn't change anymore:
   m                        N               map each d in N to:
     WghHl+dQ                                  if H[0] >= len(d+Q):
    +        d  Q                                 d + Q
              ~t                                  and decrement Q by 1
             d                                 else:
                                                  d
j                                     at the end print every row on a separate line

7

Python 2,210200字节

编辑:现在工作!

从最大的数字开始,从上到下,从左到右填充。然后,转置并再次执行。然后转置并打印。我必须为转置工作留出空间,因为这些线还没有达到其全长。

我很难进行嵌套的exec工作(要做的事情exec'exec"..."*w\n;...'*2。如果有人可以解决,请告诉我。)

n,w,h=input()
s=[""]*h
for x in 1,2:
    exec"for i in range(h):l=len(s[i]+`n`)<=w;s[i]+=`n`*l;n-=l\n"*w;s=[r.replace(" ","")for r in map(lambda x:`x`[2::5],zip(*[r.ljust(w)for r in s]))];w,h=h,w
print s

在线尝试 -使用修改后的功能,因此它可以更轻松地运行多个测试用例(并且不能使用exec)。取消注释其他版本,并修改stdin使其运行。

少打高尔夫球:

def f(n,w,h):
    s=[""]*h
    for x in 1,2:
        for j in[0]*w:
            for i in range(h):
                l=len(s[i]+`n`)<=w
                s[i]+=`n`*l
                n-=l
        s=[r.ljust(w)for r in s]
        s=map(lambda x:`x`[2::5],zip(*s))
        s=[r.replace(' ','')for r in s]
        w,h=h,w
    print"\n".join(s)

现在很有可能在所有情况下都可以使用,但是仍然可以使用(非正式)证明。;)
Martin Ender

@MartinEnder一个证明可能超出了我。为了使数字的长度变化更大,测试用例会变得非常大。它可能与是否总是有解决方案的证明有关或相同。
mbomb007'8

6

JavaScript中,284 259 245 241 240 223 209 205字节

// Golfed
let f = (N,W,H)=>eval('a=Array(H).fill("");while(N)g:{s=""+N--;d=s[L="length"];for(i in a)if(a[i][L]+d<=W){a[i]+=s;break g}for(p=0;d;++p){l=a[p][L];for(k=p+d;k>p;)l=a[--k][L]-l?W:l;while(l<W&&d)a[p+--d]+=s[d]}}a');

// Ungolfed
(N,W,H) => {
    a = Array(H).fill(""); // Create `H` empty rows.

    while (N) g : {
        s = "" + N--; // Convert the number to a string.
        d = s[L="length"]; // Count the digits in the number.

        // Loop through the rows trying to fit the number in horizontally.
        for (i in a) {
            if (a[i][L] + d <= W) { // If it fits.
                a[i] += s; // Append the number to the row.
                break g; // This is what a goto statement looks like in JavaScript.
            }
        }

        // Loop through the rows trying to fit the number in vertically.
        for (p = 0; d; ++p) {
            l = a[p][L]; // Get the length of the row.

            // Find `d` adjacent rows of the same length.
            for (k = p + d; k > p; ) {
                // If `a[--k][L] == l`, continue.
                // Else set `l` to `W` so the next loop doesn't run.
                l = a[--k][L] - l ? W : l;
            }

            // Put the characters in position.
            while (l < W && d)
                a[p+--d] += s[d];
        }
    }

    return a;
}

let test_data = [[1,1,1],
                 [6,6,1],
                 [6,2,3],
                 [10,1,11],
                 [10,11,1],
                 [11,13,1],
                 [27,9,5],
                 [183,21,21],
                 [184,2,222],
                 [200,41,12],
                 [1003,83,35]];

for (let test of test_data)
    console.log(f(test[0],test[1],test[2]));


1
使用-而不是!=测试两个数字是否不同来节省1个字节。
尼尔

2

Pyth,79 50 48字节

直到我找出错误,才进行竞争(例如[6,6,1]返回与[6,1,6]相同)。这是我第一次尝试使用Pyth,因此我可能缺少很多功能。

感谢Jakube,节省了29个字节,并使我的代码实际可用!

通过意识到repr()不需要调用来节省了另外两个字节。

基本上,这只是mbomb007的Python 2答案的翻译。

AEJmkHFb2VHVGIgGl+@JNQ XNJ~tQ)))=.[.TJkGA,HG)jJ

采用形式的输入
n
w,h


2
答案应删除,直到它们是有效的解决方案为止。
mbomb007 '16

我认为大多数代码都是正确的。我看到的唯一错误发生在换位期间。mbomb007通过小心地用空格填充剩余的列来进行转置,然后压缩并删除空格。这个保证人。转置矩阵后的w长度。=.TZ无法保证,因为它不知道length w
雅库布

其实最主要的错误是,这!>+@ZN`zK应该是!>+@ZN`zJ。然后所有小的测试用例都可以工作。但是您可以创建测试用例,在这种情况下转置会失败(如上所述)。为此,您需要类似的东西=.[.TZkK(用空字符串填充缺少的列)而不是=.TZ
雅库布

并不要将自己与Pyth混淆。在您的代码中,您有两个指向相同值(例如K@Q1)的多个变量。跟踪哪个变量是哪个值非常困难,而且...不要仅仅复制代码。把事情简单化。布尔技巧=Y...可能是Python的一个好主意,但是简单的I(如果)将更具可读性(并且更短)。
雅库布

这是一个使用mbomb007的代码的非常简单的解决方案:Linkn位于第一行(这样,我们不必将值分配给额外的变量,我们可以简单地使用Q)。而wh第二线,立即得到分配GH使用AE
雅库布

1

Stax,27 个字节

é!L↑?∞S░♠╔)¥¼/ÿµ◄÷│♦╫Δò6√√╣

运行并调试

它在for中的一行上接受输入{N} {H} {W}

该程序从指定大小的空间网格开始。对于N..中的每个数字1,它将尝试从适当大小的空格字符串到格式化的数字进行单个字符串替换。如果无法执行替换,则它将使用转置的网格再次尝试。

z)A+*   create "grid" of spaces and newlines of specified size
,Rr     create range [n ... 1]
F       for each number execute the indented section; it will fit the value into the grid
  $%z(  make a string out of spaces the same length as the number; e.g. 245 => "   "
  Y     store the space string in register Y; this will be used as a search substring
  [#    count the number of occurrences of y in the grid; the grid is still on the stack
  X     store the count in register X; this will be used as a condition
  G     jump to routine at closing curly brace
  y_$|e replace the first instance of y (the spaces) with the current number
  xG    push x; then jump to routine at closing curly brace
        end program
}       called routine jump target
C       pop top of stack; if it's truthy terminate routine
|jM|J   split on newlines; transpose; join with newlines

运行这个

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.