Приколы со строками и числами


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]


Если необходимы дальнейшие разъяснения, пожалуйста, не стесняйтесь, сообщите мне в комментариях, и я буду действовать незамедлительно.

Это , поэтому выигрывает самый короткий код в байтах для каждого языка!


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

@ 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 предметов не известна своей скоростью. Для справки, результат после Œ!будет иметь 99029007164861804075467152545817733490901658221144924830052805546998766658416222832146510162228321414102382832143849265351638597729209322288213441514989158400000000000000000000.
Эрик Outgolfer

@newguy Это решение, O(n!)но оно короткое и скорость не имеет значения. Не пытайтесь делать это с чем-то, где числа в
сумме

Может Œṙпомочь?
Арно

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 из заголовка, чтобы получить достаточно маленькую ссылку ...
Джузеппе

У меня было нечто очень похожее, принимая входные данные в качестве кадра данных. Проблема с bruteforce в том, что он не будет обрабатывать слишком большие входные данные ...
JayCe

@JayCe - возможен ли алгоритм не грубой силы, учитывая правило 3 этой задачи?
нгм

Я согласен, что это не так. Было бы интереснее без правила 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, я пропустил это. Должен был дважды проверить спецификацию, а не просто слепо следовать примеру Часа. Реализовано быстрое исправление, придется вернуться к нему позже, чтобы посмотреть, смогу ли я лучше сыграть в гольф.
лохматый

Да, третье правило подходит для esolangs, которые в любом случае могут легко перебить все решения, но это усложняет реализацию более коротких алгоритмов на других языках ... Кстати: теперь это время от времени возвращает 0 для допустимых записей.
Арно

Реализовано еще одно быстрое исправление, @Arnauld - если это не поможет, мне придется снова удалять, пока у меня не будет больше времени на его изучение. Примечание: я взял спецификацию под ее словом, что следующая строка должна выбираться случайным образом, подразумевая, что первый выбор не должен быть случайным.
Лохматый

1
@ Шэгги - я согласен, ты никогда не должен слепо следовать тому, что я делаю! :)
Час Браун

3

J, 60 53 байта

-7 благодаря FrownyFrog

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

оригинал

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

ungolfed

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

Предложения по улучшению приветствуются.

Попробуйте онлайн!


Гольф до 53
FrownyFrog

круто tyvm @FrownyFrog, я обновлю пост позже
Иона

упс, [:*/2~:/\|:в два
раза


2

Древесный уголь , 38 байт

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

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

WΦθ§κ¹«

Повторите, пока есть хотя бы один ненулевой счет.

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

Найти любой счет, который составляет более половины от остатка.

∨...ι

Если его не было, просто возьмите ненулевые отсчеты, отфильтрованные ранее.

Φ...¬⁼κυ

Отфильтруйте строку, которая была выведена в прошлый раз.

≔‽∨...υ

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

§υ⁰

Распечатать строку.

⊞υ⊖⊟υ

Уменьшить его количество.


Это приводит к неверным выводам, например, в вашем примере с ["h4x0r", 1337]включенной в качестве строки.
НГМ

@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 будут отталкивать друг друга, удаляясь друг от друга, позволяя B перемещаться между ними. Со временем это достигает хорошей смеси частиц. После каждой итерации «движения частиц» программа проверяет, что ни одна из частиц не является смежной, затем останавливается и печатает состояние системы, которое представляет собой просто список строк по порядку, как они появляются в одномерном пространстве.

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

Однако в процессе игры в гольф все это было существенно сокращено и упрощено. Теперь вместо двух одинаковых частиц отталкивающих друг друга, они просто «телепортируются». Различные частицы просто «скотча», чтобы предотвратить застой в системе. Например, если А рядом с А, он будет телепортироваться. Если A находится рядом с B, оно будет слегка сдвигаться. Затем он проверяет, выполняются ли условия (нет похожих на соседние частицы) и печатает строки по порядку, основываясь на их положении в 1-м пространстве. Это почти больше похоже на алгоритм сортировки, чем на симуляцию - с другой стороны, алгоритмы сортировки можно рассматривать как форму симулированного «дрейфа», основанного на «массе». Я отвлекся.

В любом случае, это одна из моих первых программ на Rust, поэтому я сдался после нескольких часов игры в гольф, хотя там еще могут быть возможности. Немного сложный анализ Он читает строку ввода из стандартного ввода. При желании это можно заменить на "let mut s =" [[A, 3], [B, 2]] ". Но сейчас я делаю 'echo [[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!();
}

Это интересный способ думать об этой проблеме, мне это нравится. Насколько хорошо это делается на практике? Я чувствую себя какL2предел может быть слишком низким, что может быть слишком много ложных отрицаний, когда алгоритм считает, что нет действительного вывода, когда он есть - но я не смог проверить эту теорию, поскольку у TIO, очевидно, нет regexящика.
sundar - Восстановить Монику

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


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.