Цілі, зібрати!


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відповідає кількості цифр в цілих числах від 1до Nвключно, і що замощення прямокутника в заданих числа існує. На даний момент я не маю доказів, чи це завжди можливо, але мені було б цікаво, якщо ви це зробите.

Вихідним може бути або окремий рядок, відокремлений подачею рядків, або список рядків (по одному для кожного рядка) або список списків одноцифрових цілих чисел (по одному для кожної комірки).

Результати подання заявки повинні бути визначальними, і ви повинні мати можливість обробляти всі тестові справи менше ніж за хвилину на розумній настільній машині.

Ви можете написати програму чи функцію та скористатися будь-яким із наших стандартних методів отримання вводу та надання виводу.

Ви можете використовувати будь-яку мову програмування , але зауважте, що ці лазівки за замовчуванням заборонені.

Це , тому найкоротший вірний відповідь - вимірюється в байтах - виграє.

Випробування

За винятком першого, жодне з них не є унікальним. Кожен тестовий випадок 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
Чи є докази того, що це завжди можливо?
Фаталізувати

@ Фаталізувати Добре питання насправді. Ви можете припустити, що це можливо для всіх заданих даних, але доказ будь-якого способу був би цікавим.
Мартін Ендер

@ Фаталізувати: Принаймні, у тривіальному випадку введення (10, 1, 1), це неможливо (якщо припустити, що Nу побудові повинні бути використані всі числа від 1 до ПО). Якщо це обмеження виконується, площа прямокутника в одиницях повинна бути принаймні кількістю цифр 1..N, щоб зробити це можливим. Якщо це обмеження послаблене, це можливо у всіх випадках (але тоді виклик не дуже веселий: P)
Себастьян Ленартович

2
@SebastianLenartowicz: Я думаю, ви пропустили ту частину, де сказано, що площа прямокутника відповідає сумі цифр чисел у [1, N]. Якщо N == 10, то ширина і висота повинні бути 1 і 11. Якщо ширина або висота дорівнює 1, ця проблема завжди вирішується.
Yay295

1
@MartinEnder Також може бути цікавим протилежне завдання: перерахунок цифр як вхідних даних (і врешті-решт N, але програма може обчислити їх із ширини та висоти), і програмі потрібно перевірити, чи прямокутник є достовірною відповіддю на це завдання. ...
Дада

Відповіді:


3

Pyth, 35 байт

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

Кредити mbomb007. Я використовував його алгоритм. Спочатку я хотів лише допомогти Стівену Х., але потім дуже хотів побачити коротку версію.

Переходить 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, 210 200 байт

Редагувати: працює зараз!

Заповнюється зверху вниз, зліва направо, починаючи з найбільшої кількості. Потім перенесіть і зробіть це ще раз. Потім перемістіть та роздрукуйте. Мені довелося прокладати пробіли для переміщення на роботу, оскільки лінії ще не на повну довжину.

У мене виникли проблеми з вкладеною вкладеною 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)

Це дуже ймовірно, що це має працювати зараз у всіх випадках, але (неофіційний) доказ все-таки буде вдячний. ;)
Мартін Ендер

@MartinEnder Доказ, мабуть, поза мною. Щоб номери відрізнялися більше за довжиною, тестові випадки стають дуже великими. Це, мабуть, пов'язане з тим же доказом, чи завжди існує рішення.
mbomb007

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

Піта, 79 50 48 байт

Не конкуруючи, поки я не працюю з помилками (наприклад, [6,6,1] повертає те саме, що і [6,1,6]). Вперше я намагаюся використовувати Pyth, тому мені, мабуть, не вистачає багатьох функцій.

Завдяки Jakube, врятував 29 байт і змусив мій код фактично працювати!

Зберегли ще два байти, зрозумівши, що repr()дзвінки непотрібні.

Це в основному лише переклад відповіді Pybomon 2 mbomb007.

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

Вводиться у вигляді
n
w,h.


2
Відповіді слід видалити, поки вони не стануть правильним рішенням.
mbomb007

Я думаю, що більшість коду є правильними. Єдина помилка, яку я бачу, трапляється під час транспозиції. mbomb007 переміщує, ретельно заповнюючи пробіли, що залишилися, потім переміщуючи та видаляючи пробіли. Це гарантії. що після транспонування матриця має wдовжину. =.TZне можу цього гарантувати, оскільки він не знає довжини w.
Якубе

Насправді головна помилка в тому, що !>+@ZN`zKмає бути !>+@ZN`zJ. Потім працюють всі невеликі тестові справи. Але ви можете створити тестові випадки, коли перенесення не вдається (як описано вище). Для цього вам потрібно щось на зразок =.[.TZkK(заповнити пропущені стовпці порожніми рядками) замість =.TZ.
Jakube

І намагайся не плутати себе з Пітом. У своєму коді у вас є дві множинні змінні, які вказують на однакові значення (як Kі @Q1). Було досить важко відстежити, яка змінна - яке значення, ... І не просто копіювати код. Не ускладнювати. Булева хитрість =Y...може бути хорошою ідеєю для Python, але простий I(якщо) буде набагато легше читати (а також коротше).
Jakube

Ось дійсно просте рішення з використанням коду mbomb007: Посилання Це займає nперший рядок (таким чином, нам не потрібно присвоювати значення додатковій змінній, ми можемо просто використовувати Q). А wта hна другій лінії, які отримують відразу присвоєного Gі Hз AE.
Jakube

1

Стакс , 27 байт

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

Запустіть і налагоджуйте його

Він займає введення в одному рядку для {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

Виконати цей

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.