Цибульне програмування


22

Використовуючи лише друкований ASCII (шістнадцяткові коди від 20 до 7E), запишіть квадратну основну програму N × N без коментарів, яку оточують ще 4 шари , створюючи (N + 8) × (N + 8) квадратну програму (N> 0) . Для N = 3 макет (замінений фактичним кодом) виглядає так:

44444444444
43333333334
43222222234
43211111234
4321CCC1234
4321CCC1234
4321CCC1234
43211111234
43222222234
43333333334
44444444444
  • C представляють основну програму 3 × 3.
  • 1-ї представляють перший шар, 2-х представляють другий шар і т.д.

Програма завжди займає ряд цілих чисел, розділених простором, таких як 0 -1 31 -1 2 2 2stdin або подібні (це повинні бути просто прості числа, відсутність лапок чи дужок чи що-небудь). Вихід залежить від того, які частини макета були виконані.

Існує п’ять способів запуску програми (нові рядки включаються в пробіг). Кожен робить щось інше до списку:

  1. Запустити лише основне:

    CCC
    CCC
    CCC
    

    Це обчислює максимум абсолютних значень елементів вхідного списку та друкує COREновий рядок багато разів. Якщо максимум 0, нічого не виводиться (новий рядок є нормальним).

    • Вихід для 0 -1 31 -1 2 2 2буде

      CORE
      CORE
      ...
      

      31 раз.

  2. Запустіть ядро ​​шаром 1:

    11111
    1CCC1
    1CCC1
    1CCC1
    11111
    

    Це виводить середнє значення ( середнє арифметичне ) значень списку до стандартної точності з плаваючою точкою.

    • Вихід для 0 -1 31 -1 2 2 2буде 35/7 = 5( 5.0це нормально).
  3. Запустіть серцевину шарами 1 і 2:

    2222222
    2111112
    21CCC12
    21CCC12
    21CCC12
    2111112
    2222222
    

    Це виводить розділений пробілом список списку входів, перевернутий.

    • Вихід для 0 -1 31 -1 2 2 2буде 2 2 2 -1 31 -1 0.
  4. Виконайте серцевину шарами 1, 2 і 3 (візерунок повинен бути очевидним).
    Це виводить розділений пробілом список відсортованого списку входів.

    • Вихід для 0 -1 31 -1 2 2 2буде -1 -1 0 2 2 2 31.
  5. Запустіть ядро ​​шарами 1, 2, 3 і 4.
    Це виводить розділений пробілом список вхідних даних із видаленими дублікатами, впорядкування не має значення.

    • Вихід для 0 -1 31 -1 2 2 2може бути -1 0 2 31.

Весь вихід призначений для stdout або подібної альтернативи.

Тільки ці 5 комбінацій компонування мають визначене поведінку.

Примітки

  • Не допускаються коментарі в ядрі або шарах або їх комбінаціях. Код, який не відповідає або не робить нічого конструктивного, не вважається коментарем.
  • Пам’ятайте, що ядро ​​може мати будь-які (позитивні) N × N розміри, але шари товщиною лише одного символу.
  • Ви можете припустити, що на вході немає провідних або кінцевих пробілів і рівно один пробіл між числами. Він завжди буде містити принаймні одне число. (Вихідні списки також повинні бути відформатовані так.)
  • Ви можете припустити, що список та обчислення, необхідні для виводу, не матимуть значень, які переповнюють (або переповнюють) ваші цілі числа (до тих пір, поки їх макс є чимось розумним, як 2 16 ).

Оцінка балів

Написати цю програму зазвичай було б просто. Написати це з невеликим стрижнем важко.

Виграє програма з найменшим розміром ядра (найменшим N). У разі зв’язків переможцем стає повна програма (квадрат (N + 8) × (N + 8) з найменшими чіткими символами (не рахуючи нових рядків).

Будь ласка, повідомте про своє значення N у верхній частині відповіді.


1
Я подумав, що це також буде ще один із тих нових типів
оптимізатор

Чи можу я використовувати мову, яка ігнорує все після нового рядка?
isaacg

1
@isaacg Так (поки новий рядок не вважається символом коментаря, що було б дивним).
Хобі Кальвіна

3
@Optimizer Не спокушайте мене ... " Кожна відповідь додає новий шар коду цибулі, щоб він робив щось нове зі списком ... "
Захоплення Кальвіна

1
@Optimizer No. (Я знаю, що ці правила введення-виводу є настільки суворими, але це потрібно для того, щоб речі були узгоджені між мовами.)
Хобі Calvin's

Відповіді:


10

CJam, N = 5, 27 (26) унікальних символів

Це 26 символів, якщо я не рахую пробілів. Програму насправді можна перетворити на ту, що не використовує пробіли, просто заповнивши всі порожні пробіли без відключення (наприклад, _;що дублює верхній елемент стека, а потім відкидає, або шляхом сортування масиву знову і знову), але це просто відволічеться від фактичного коду.

l~]_|S*      
{l~]$S*      
 {l~]W%S*    
  {l~]_,\    
   {l~]{z    
    }%$W=    
    "CORE    
    "*       
         }   
   ;:+d\/ }  
  ;        } 
 ;          }
;            

Перевірте це тут.

Ядро є

l~]{z
}%$W=
"CORE
"*

(Плюс порожній рядок.)

Я досить впевнений, що цього N = 4не можна зробити в CJam (і я впевнений, що Денніс переконає мене в іншому: D). Наведене вище має 17 символів, і хоча це може бути можливо зменшити до 16 (наприклад, якщо у CJam не було помилки, щоб задихнутися :z, що вимагає {z}%, або використовуючи ARGV), я не думаю, що ви можете це вмістити в макеті, не вводячи перерив рядка всередині CORE.

Усі реалізації є дуже простими рішеннями задач. Усі вони починаються з того, l~]що читає STDIN, оцінює його і поміщає в масив.

Попередній шар завжди оточений {...}, що робить його блоком, який не виконується автоматично. І замість того, щоб виконати його, я просто відкидаю його зі стека ;, тому жоден шар не залежить від коду в попередньому шарі. У шарі 1 код не вписався у перший рядок, тому я продовжив його після відкидання основного блоку.

Тепер про фактичні програми:

  • Основна:

    {z}%$W="CORE
    "*
    

    Зіставте absна карті список, відсортуйте його, візьміть останній елемент, повторіть CORE(і розрив рядка), що багато разів.

  • Шар 1:

    _,\:+d\/
    

    Скопіюйте список, візьміть довжину, поміняйте елементи стека, отримайте суму, накинуту double, поміняйте елементи стека, розділіть. Я думаю, що це може бути коротшим, але немає стимулів для цього.

  • Шар 2:

    W%S*
    

    Зворотний масив, рифлінг з пробілами.

  • 3 рівень:

    $S*
    

    Сортуйте масив, розкажіть пробіли.

  • Шар 4:

    Скопіюйте, візьміть встановлений союз, розкажіть пробіли.

Можливі також деякі інші оптимізації, наприклад повторне використання ;та *Sрівня 2, але знову ж таки, але це не впливає на показник.


17

Python 2 - N = 17, 53 символи

О, я люблю проблеми з компонуванням джерела з Python ...

i=4                     ;
ii=3                    ;
iii=2                   ;
iiii=1                  ;
iiiii=0;R=raw_input     ;
iiiii;w=R().split()     ;
iiiii;n=map(int,w)      ;
iiiii;S=set(n);M=max    ;
iiiii;s=sorted(n)       ;
iiiii;J="\n".join       ;
iiiii;j=" ".join        ;
iiiii;k=M(map(abs,n))   ;
iiiii;A=J(["CORE"]*k)   ;
iiiii;B=sum(n)/len(n)   ;
iiiii;C=j(w[::-1])      ;
iiiii;D=j(map(str,s))   ;
iiiii;E=j(map(str,S))   ;
iiiii;P=A,B,C,D,E       ;
iiiii;print P[i]        ;
iiiii;" /__----__\  "   ;
iiiii;"|/ (')(') \| "   ;
iiii;"  \   __   /  "   ;
iii;"   ,'--__--'.   "  ;
ii;"   /    :|    \   " ;
i;"   (_)   :|   (_)   ";

Але все ще є кілька невикористаних пробілів.

Я б ще міг покращити кількість унікальних символів, але я буду дотримуватися кращої читабельності - якщо вона взагалі є.

Редагувати: О, це знову Стен !


Напевно, ви можете зберегти деякі рядки, вибравши друк замість i=*хитрості
M.Herzkamp

@ M.Herzkamp: Зміна printPython 2. неможлива. Але, мабуть, є можливість для вдосконалення - можливо, за допомогою Python 3.
Falko

Я не знаю Python, але чи не відсутнє це абсолютне значення у вихідному коді основного коду -c*max(n)
nutki

@nutki: Ти маєш рацію! Я не читав уважно. Але мені вдалося це виправити.
Фалько

6

Python 3: N = 11, 40 різних символів

if 1:              
 if 1:             
  if 1:            
   if 1:           
    p=print;R=0    
    a=input()      
    b=a.split()    
    m=map;a=abs    
    E=max;l=len    
    n=m(int,b);    
    C=['CORE']     
   "R=E(m(a,n))"   
   OO=C*R;s=sum    
   "x='\n'.join"   
   "p(x(O))    "   
  "p(s(n)/l(b)) "  
 "p(*b[::-1])    " 
"p(*sorted(n))    "
p(*set(n))         

Дякую @Falko за те, що моя музика. Це працює, тому що Python не створює нову область для кожного оператора if, тому змінні зберігаються у зовнішніх printоператорах. Одна дратівлива річ полягала в тому, що mapпредмет (у нашому випадку n) можна використовувати лише один раз. Тож треба було накреслити R=E(...)рядок, але потім Rне було визначено. Тому мені пощастило, що в першому рядку залишилось чотири пробіли!

Вихід може бути вирішений шляхом надання декількох елементів *b[::-1]замість списку. Альтернатива ' '.join(...)була б занадто довгою.


Гарний! Приємно бачити альтернативний підхід для вирішення змінних початкових ліній у python. Просто кілька коротких if-висловлювань і всі ці пробіли просто чудові. :)
Фалько

@Falko: Недоліком є: для Стен немає місця :(
M.Herzkamp

2

C (gcc) , N = 15, 47 унікальних символів

Припускає sizeof(int) == 4і sizeof(int*) >= sizeof(int).

;                     ;
 ;                   ; 
  ;                 ;  
   ;           float   
    s;c(a,b)int*a,*    
    b;{b=*b-*a;}i,n    
    ,*f;*q,*R,C,E ;    
    main(a){for(;0<    
    scanf("%i",&a);    
    i=i<abs(a)?a:i,    
    s+=f[n-!0]=a)f=    
    realloc(f,++n*4    
    );qsort(f,n*C,4    
    ,c);for(i=q?R?n    
    :!0:i;i--;a=f[i    
    ])!E|n-i<2|a!=f    
    [i]&&printf(q?R    
    ?R:q:"CORE\n",!    
    q+R?f[i]:s/n);}    
   ;*q="%f";       ;   
  ;*R="%.0f ";      ;  
 ;C=!0;              ; 
;E=!0;                ;

4 шари

3 шари

2 шари

1 шар

Основні


0

Рунічні чари , N = 9 N = 8, 38 символів

/ o/\  \     \S\
" //RiU\      \}
@            q "
"        }+1\r @
}   ^U \    {q "
     \{\?)}\+  }
  o\/'|A:{:/R' S
 //r/Ril2=?\?R :
   ,A~/"OC"/=? {
   @| \"RE"\3= =
 D$\' /rqka/l2S?
    i \*@   il\/
   'R1i     Ui ~
 R$/Rak      U \
 ?!D  Rlril1-{=
R   R: }S:{=?\~

Спробуйте в Інтернеті!

Виявляється, я помилявся , я забув, що вже мав явну oкоманду s rt через те, що раніше стикався з проблемою "сортування списку". Це, однак, обмежує розмір входів, які може прийняти кінцева програма (8 значень) через внутрішні витрати команди сортування. Невеликий твік може збільшити розмір вводу до 13 ціною 1 унікального символу або до 19 для двох унікальних символів (усі додаткові символи знаходяться на рівні 1 та додаються одночасно, але збільшена ємність стеку IP не є необхідний до рівня 3, оскільки C, L1 і L2 можуть виконати свої обчислення, не утримуючи весь вхід у пам'яті).

Основна: Спробуйте в Інтернеті!

Шар 1: Спробуйте в Інтернеті!

Шар 2: Спробуйте в Інтернеті!

3 рівень: Спробуйте в Інтернеті!

Шар 4: Спробуйте в Інтернеті!

Подальше стиснення малоймовірне, через менший простір, що потребує збільшення кількості символів управління потоком. Я знайшов розташування, яке дало 9 порожніх пробілів в основній програмі, але цього недостатньо, як нам потрібно (правильно розташований) 15.

Пояснити, як працює будь-яка з цих програм, важко без візуальної карти шляху, який проходить ІС, що є громіздким і забирає багато часу для побудови. Початкова точка входу - лівий верхній кут програми Core (^ ), який дозволяє послідовно керувати потоком, оскільки додаються нові шари, оскільки кожен шар має можливість перехоплюватися на щойно доданій лінії у верхній або нижній частині.

Шари 1 і 2 перехоплюють внизу (так, щоб верхня лінія залишалася порожньою для майбутніх шарів), а потім виконували свої операції вздовж правого краю (петля, розташована вертикально). Шар 1 трохи задовгий і також займає 3 символи по верхньому краю, але діагональний відбивач (\ ) у верхньому правому куті вирівнює IP із наступною ітерацією циклу.

Шар 3 перехоплює уздовж верхнього краю для того, щоб схопити перше вхідне значення перед перенаправленням на нижній край (шар 4 залишає NOP у цьому стовпчику на нижньому рядку) і зчитує повне введення, використовуючи петлю нижнього краю, перенаправляючи вниз команда ( D) внизу зліва. Звідти IP відскакує кілька разів, перш ніж опинитися у $циклі output ( ) ліворуч, щоб розділити значення.

Шар 4 використовує всю функціональність шару 3 (отже, порожній простір), але перехоплює власний новий верхній край (верхній лівий край) для того, щоб виконувати власну функціональність в кінці обробки рівня 3. У верхній лівий кут вставляється рядок, "@"який використовується для позначення кінця масиву перед введенням циклу обробки вздовж нижнього. Якщо знайдено повторюване значення, воно з’явиться (в ~нижньому правому куті), інакше буде взята гілка, яка споживає новий правий край. Ця бічна гілка перевіряє, чи досягнутий кінець масиву, і якщо це так, вирветься та перейдіть до того самого виведеного проміжком вихідного циклу з рівня 3. В іншому випадку використовуйте порожній простір на рівні 3 для повернення до основного петля.

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