Весело за допомогою струн та цифр


13

Ось головоломка програмування для вас:

Наприклад [[A,37],[B,27],[C,21],[D,11],[E,10],[F,9],[G,3],[H,2]], вказавши список пар рядків і відповідних чисел, виведіть інший список, який буде мати лише рядки таким чином:

  1. Загальний підрахунок будь-якого рядка повинен бути точно рівним його відповідному номеру у вхідних даних.

  2. Жодна рядок не повинна повторюватися сусідньо в послідовності, і кожна рядок повинна відображатися у вихідному списку.

  3. Вибір наступного рядка слід робити випадковим чином до тих пір, поки вони не перепадають вище двох правил. Кожне рішення повинно мати ненульову ймовірність бути обраним.

  4. Якщо комбінація неможлива, вихід повинен бути справедливим 0.

Список введення може бути поданий у будь-якому порядку (відсортований чи несортований), а рядки у списку можуть бути будь-якої довжини.


Вибірка зразка для вищевказаного вхідного зразка 1

[A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,C,A,C,A,C,A,C,A,C,A,C,A,C,A,C,A,C,A,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,E,F,E,F,E,F,E,F,E,F,E,F,E,F,E,F,E,F,E,G,H,G,H,G]


Зразок введення 2:

[[A,6],[B,1],[C,1]]

Вихід для другого входу:

0

оскільки список не можливий на основі правил.


Приклад 3:

[[AC,3],[BD,2]]

дійсний вихід: [AC,BD,AC,BD,AC]

недійсний вихід: [AC,BD,AC,AC,BD]


Якщо потрібне додаткове роз'яснення, будь ласка, не соромтесь сказати мені у коментарях, і я негайно діятиму відповідно до цього.

Це , тому найкоротший код у байтах для кожної мови виграє!


Приємний виклик! Я думаю, що це трохи не визначено нашими стандартами. Я настійно рекомендую використовувати The Sandbox, щоб отримати багато відгуків перед тим, як опублікувати виклик, щоб ви не отримували голосування або закриття голосів! :-) Я з нетерпінням чекаю на вас більше хороших викликів!
Джузеппе

@Giuseppe дякую, я спробую пройти це. Повідомте мене, чи потрібно мені додати якісь деталі, якщо я пропустив у цій.
Stupid_Intern

1
Чи можемо ми взяти 2 входи, лише рядки і просто цифри?
FrownyFrog

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

Відповіді:


6

Желе , 11 байт

Œṙ'Œ!⁻ƝẠ$ƇX

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

Œṙ'Œ!⁻ƝẠ$ƇX Arguments: z
  '         Flat: Apply link directly to x, ignoring its left and right depth properties
Œṙ            Run-length decode
   Œ!       Permutations of x
         Ƈ  Filter; keep elements of x for which the link returns a truthy result
        $     ≥2-link monadic chain
      Ɲ         Apply link on overlapping pairs (non-wrapping)
     ⁻            x != y
       Ạ        Check if all elements of x have a truthy value (+vacuous truth)
          X Pick a random element of x; return 0 if the list is empty.

Якби Œṙне векторизуватись, це працювало б без'
dylnan

5

Желе , 17 байт

Wẋ¥Ɲ€ẎẎŒ!Œɠ’SƊÐḟX

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


Коли я намагаюся, ["A", 100], ["B", 3]це не дає нічого, що я застряв, я думаю.
Stupid_Intern

1
@newguy Генерування всіх перестановок із 103 предметів не славиться своєю швидкістю. Для довідки, результат після Œ!буде мати 99029007164861804075467152545817733490901658221144924830052805546998766658416222832141441073883538492653516385977292093222882134415149891584000000000000000000000000000000000000.
Ерік Аутгольфер

@newguy Це рішення є, O(n!)але воно коротке і швидкість не має значення. Не намагайтеся ні з чим, коли цифри складають більше ніж приблизно 6-8: P
HyperNeutrino

Може Œṙдопомогти?
Арнольд

1
@dylnan Я не думаю, що це працює для рядків, з якими я спробував, ["AT", 3], ["B", 3]і отримав TBATATBABяк вихід, що невірно
Stupid_Intern

5

Python 2 , 114 189 185 174 байт

from random import*
a=input()
s=u=[]
while a:x,y=a.pop(a.index(next((w for w in a if w[1]>sum(v[1]for v in a+u)/2),choice(a))));s=s+[x];a+=u;u=[[x,y-1]]*(y>1)
print[s,0][y>1]

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

Ой! Набагато складніше з правилом 3 ... :). Все ще намагаюся уникати O(n!)підходу, щоб він міг обробляти всі тестові випадки десь до теплової смерті Всесвіту ...

Алгоритм: припустимо, загальна сума підрахунків рядків дорівнює t. Якщо якась - або рядок має відлік nз 2*n>t+1, то це не представляється можливим , щоб задовольнити обмеженням. Тому, якщо будь-який рядок ( за винятком раніше обраниці) має лічильник nз 2*n=t+1, то ми повинні вибрати цей рядок в наступному. В іншому випадку ми можемо вибрати навмання будь-який рядок, який не є раніше вибраною.


1
@Arnauld: повністю пропустив це! виправлено зараз.
Час Браун

4

R , 148 141 байт

function(x,y,p=combinatXXpermn(rep(seq(y),y)),q=which(sapply(lapply(p,diff),all)))"if"(n<-sum(q|1),"if"(n-1,x[p[[sample(q,1)]]],x[p[[q]]]),0)

Спробуйте в Інтернеті! (Я скопіював combinat::permnі назвав його combinatXXpermnтам.)

Розчин брутальної сили O (n!).

Використовує permnз combinatупаковки для створення всіх можливих замовлень. Потім перевіряє, чи хтось дотримується правил, і вибирає одне з них навмання.


n<-sum(n|1)я вважаю, що байт коротший. Але примха sampleз введенням довжини один тут дуже засмучує.
Джузеппе

гольфували його трохи, також спробуйте тут - мені довелося вилучити combinatXXpermn із заголовка, щоб отримати посилання досить малим ...
Джузеппе

У мене було щось дуже схоже, приймаючи дані як кадр даних. Проблема з
грубою силою

@JayCe - чи можливий алгоритм безсильних сил, враховуючи правило 3 цього виклику?
ngm

Я згоден, це не може. Було б цікавіше без правила 3.
JayCe

3

JavaScript, 112 байт

Спочатку пройдіть це, ще більше гольфу (сподіваємось) слід.

f=([i,...a],o=[])=>a.sort((x,y)=>(y[1]-x[1])*Math.random()-n*.5,n=--i[1],o.push(i[0]))+a?f(n?[...a,i]:a,o):n?0:o

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


1
Дякую, @Arnauld, я це пропустив. Якщо ви двічі перевірили специфікацію, а не сліпо слідуючи за результатами Chas. Виконавши швидке виправлення, доведеться повернутися до нього пізніше, щоб побачити, чи зможу я його краще взяти в гольф.
Кудлатий

Так, 3-е правило нормально для esolangs, яке може легко змусити всі рішення все одно, але це ускладнює реалізацію коротших алгоритмів іншими мовами ... BTW: тепер, здається, час від часу повертається 0 на дійсних записах.
Арнольд

Реалізовано ще одне швидке виправлення, @Arnauld - якщо це не сортує, мені доведеться видалити ще раз, поки не матиму більше часу на розгляд. Примітка: Я взяв специфікацію в своєму слові, що наступний рядок потрібно вибирати випадковим чином, маючи на увазі, що перший вибір не повинен бути випадковим.
Кудлатий

1
@Shaggy - Я погоджуюсь, ти ніколи не слід сліпо слідувати нічого, що я роблю! :)
Час Браун

3

J, 60 53 байти

-7 завдяки FrownyFrog

(?@#{])@(#~*/@(2~:/\])"1)@(]i.@!@#@;A.;) ::0(#~>)/&.>

оригінальний

(?@#{])@(#~2&([:*/~:/\)"1)@(A.~i.@!@#)@;@:(([#~>@])/&.>) ::0

неозорий

(?@# { ])@(#~ 2&([: */ ~:/\)"1)@(A.~ i.@!@#)@;@:(([ #~ >@])/&.>) ::0

Пропозиції щодо вдосконалення вітаються.

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


Гольфував до 53
FrownyFrog

чудовий tyvm @FrownyFrog, я оновлю пост пізніше
Jonah

oops, [:*/2~:/\|:є дві коротші
FrownyFrog


2

Вугілля деревне , 38 байт

WΦθ§κ¹«≔‽Φ∨Φι›⊗§κ¹ΣEι§μ¹ι¬⁼κυυ§υ⁰⊞υ⊖⊟υ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

WΦθ§κ¹«

Повторіть, хоча є хоча б одна ненульова кількість.

Φι›⊗§κ¹ΣEι§μ¹

Знайдіть будь-яку кількість, що становить більше половини залишку.

∨...ι

Якщо такого не було, то просто візьміть ненульові підрахунки, відфільтровані раніше.

Φ...¬⁼κυ

Відфільтруйте рядок, який виводився останній раз.

≔‽∨...υ

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

§υ⁰

Роздрукуйте рядок.

⊞υ⊖⊟υ

Зниження її кількості.


Це створює недійсні результати, наприклад, у вашому прикладі з ["h4x0r", 1337]включеними як рядок.
ngm

@ngm Я змінив код і тепер він виходить з ладу, якщо ви це зробите ... належна перевірка, на жаль, коштуватиме більше байтів.
Ніл

2

Рубін , 85 байт

Підхід грубої сили (дякує Йона за ідею).

->l{l.flat_map{|a,b|[a]*b}.permutation.select{|p|r=0;p.all?{|a|a!=r&&r=a}}.sample||0}

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

Рубі , 108 100 96 байт

Раніше підхід Богоссорта

->l{w=[];l.map{|a,b|w+=[a]*b;b}.max*2>w.size+1?0:(w.shuffle!until(r='';w.all?{|a|a!=r&&r=a});w)}

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



2

Іржа 633 байт

Те, що робить це трохи іншим, ніж інші, - це те, що він почав з ідеї переставити рядки, імітуючи фізичну систему. Кожен рядок спочатку дублюється відповідною кількістю разів. Потім кожна окрема струна трактується як частинка в просторі. Дві частинки з однаковим струнним значенням "відштовхують" одна одну, тоді як дві частинки з різними значеннями притягують одна одну. Наприклад, якщо ми почнемо з AAAAAAABBBBCC, As будуть скасовувати один одного, віддаляючись один від одного, дозволяючи Bs рухатися між ними. З часом це досягає приємної суміші частинок. Після кожної ітерації «руху частинок» програма перевіряє, чи не є однакові частинки, а потім зупиняється та друкує стан системи, що є просто списком рядків у порядку, як вони з’являються в 1-мірному просторі.

Тепер, коли мова заходить про те, щоб реально реалізувати цю фізичну систему, вона почалася, використовуючи стару модну демонстраційну / ігрову техніку ПК, щоб зберігати кожну позицію та швидкість частинок як числа, а потім проходити ітерації для оновлення положення та швидкості. При кожній ітерації ми додаємо швидкість до положення (руху), а також додаємо прискорення до швидкості (зміна швидкості руху) та обчислюємо прискорення (знаходження сили на частинку). Для спрощення система не розраховує силу на кожну частинку на основі всіх інших частинок - вона лише перевіряє частинки, що знаходяться безпосередньо поруч. Був також ефект «демпфування», щоб частинки не надто прискорювались і відлітали до нескінченності (наприклад, швидкість зменшується на х відсотків на кожен крок).

Однак у процесі гольфу все це було скорочено та спрощено. Тепер замість двох однакових частинок, що відштовхуються одна від одної, вони просто "телепортуються". Різні частинки просто "забивають" шматочки, щоб запобігти застою в системі. Наприклад, якщо A поруч з A, він телепортується. Якщо A поруч із B, він лише трохи зміститься. Потім він перевіряє, чи виконуються умови (не так, як сусідні частинки) і друкує рядки в порядку, виходячи з їх положення в 1-денному просторі. Це майже більше схоже на алгоритм сортування, ніж на моделювання - тоді знову можна побачити алгоритми сортування як форму імітованого «дрейфування» на основі «маси». Я відволікаюсь.

У всякому разі, це одна з моїх перших програм «Іржа», тому я відмовився після кількох годин гри в гольф, хоча можливо ще є можливості. Біт розбору для мене важкий. Він зчитує вхідний рядок зі стандартного вводу. За бажанням це можна замінити на "нехай mut s =" [[A, 3], [B, 2]] ". Але зараз я 'повторюю [[A, 3], [B, 2]] | вантажний пробіг 'у командному рядку.

Розрахунок зупинки - це чимала проблема. Як визначити, якщо дійсний стан системи ніколи не буде досягнутий? Перший план полягав у тому, щоб виявити, чи коли-небудь "поточний" стан коли-небудь повторював старий стан, наприклад, якщо ACCC змінюється на CACC, але потім повертається до ACCC, ми знаємо, що програма ніколи не припиняється, оскільки це лише псевдослучайно. Тоді слід відмовитись та надрукувати 0, якщо це сталося. Однак це здалося величезною кількістю Rust-коду, тому натомість я просто вирішив, що якщо він пройде через велику кількість ітерацій, він, ймовірно, застряг і ніколи не досягне сталого стану, тому він друкує 0 і зупиняється. Скільки? Кількість частинок у квадраті.

Код:

extern crate regex;
struct P {s:String,x:i32,v:i32}
fn main() {
    let (mut i,mut j,mut p,mut s)=(0,0,Vec::new(),String::new());
    std::io::stdin().read_line(&mut s);
    for c in regex::Regex::new(r"([A-Z]+),(\d+)").unwrap().captures_iter(&s) {
        for _j in 0..c[2].parse().unwrap() {p.push(P{s:c[1].to_string(),x:i,v:0});i+=1;}
    }
    let l=p.len(); while i>1 {
        j+=1;i=1;p.sort_by_key(|k| k.x);
        for m in 0..l {
            let n=(m+1)%l;
            if p[m].s==p[n].s {p[m].v=p[m].x;if n!=0 {i=2}} else {p[m].v=1}
            p[m].x=(p[m].x+p[m].v)%l as i32;
        }
        if j>l*l{p.truncate(1);p[0].s="0".to_string();i=1}
    }
    for k in &p{print!("{}",k.s)};println!();
}

l2regex

він передав приклади, я його годував, хоча я його не роздував. я змінив його для роботи в TIO, вам потрібно змінити 'let s = [("A", 3), ("B", 2), ("ZZ", 4)];' лінія, bit.ly/2LubonO
яскравий


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