Предикат цепочки чисел


27

Проблема:

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

Например, следующее должно вернуть truey:

[1, 12, 203, 0, 30]
             ^   ^ Contains a 0
        ^ Contains a 2
    ^ Contains a 1

Следующее должно вернуть фальси:

[1, 32, 23, 34]
    ^ Doesn't contain a 1, therefore false

Ваше представление может быть функцией или полной программой.

Входные данные:

Ввод может быть любой разумный тип последовательности. Массив чисел, массив строк, разделенная строка чисел и т. Д.

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

Ввод может быть взят через стандартный ввод или в качестве аргумента.

Вы можете предположить:

  • все числа будут неотрицательными целыми числами

  • вход всегда будет содержать как минимум 2 числа

  • ввод цифр не начинается с 0

Выход:

Выводом будет истинное или ошибочное значение (как определено вашим языком), показывающее, соблюдается ли вышеуказанная спецификация или нет.

Значения истина / ложь не должны быть согласованными между тестами.

Он может быть либо выведен на стандартный вывод, либо возвращен.

Тестовые случаи:

True cases:
[1, 1, 1, 11, 111, 11, 1]
[12, 23, 34, 45, 56]
[65, 54, 43, 32, 21]
[123, 29, 9, 59, 55, 52, 2017, 2]
[1234567890, 19, 95, 5012, 23]

False cases:
[1, 2, 3, 4, 5, 1, 11] (2 doesn't contain a 1)
[12, 23, 33, 45] (45 doesn't contain a 3)
[98, 87, 76, 11, 12, 23] (11 doesn't contain a 7 or 6)

Это код-гольф, поэтому выигрывает наименьшее количество байтов.

Ответы:


7

Желе , 5 4 байта

f2\Ạ

Ввод представляет собой массив строк.

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

Как это работает

f2\Ạ  Main link. Argument: A (array of strings)

 2\   Pairwise reduce by:
f       Filter, yielding all chars in the left string that appear in the right one.
   Ạ  All; yield 1 if all strings are non-empty, 0 if not.


12

Сетчатка , 25 20 байт

(.).*¶(?=.*\1)

^.+$

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

Всякий раз, когда мы находим цифру, которая также встречается в следующем номере, мы удаляем разделитель между этими числами (вместе с цифрами в первом номере, начиная с общего, но это не имеет значения). Ввод действителен, если все разделители были удалены в процессе, который мы проверяем, убедившись, что строка может быть сопоставлена ​​как одна строка.


11

Брахилог , 9 байт

{⊇ᵐ=∧?t}ˡ

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

Обратите внимание, что это работает не только со списком целых чисел, но также со списком строк или списком списков.

объяснение

{      }ˡ       Left fold on the input:
 ⊇ᵐ=              It is possible to find a number which is a subset of both input numbers
    ∧             (and)
     ?t           The output is the second number (to continue the fold)

2
Это круто. Кажется ... декларативным? Читается так, будто вы просто говорите языку спецификации.
Carcigenicate

3
@Carcigenicate Brachylog действительно декларативный, он основан на языке декларативного логического программирования Prolog .
Роковая

2
Пролог на самом деле в моем (все более и более) длинном списке языков для изучения, когда я получаю неограниченное свободное время. Слишком много классных языков!
Carcigenicate

8

JavaScript (ES6), 47 44 * 43 байта

Сохранено байт благодаря @Neil

x=>x.every(y=>y.match(`[${p}]`,p=y),p=1/19)

Принимает ввод в виде списка строк.

Тестовый фрагмент

* ( зачеркнуто 44, по-прежнему регулярно 44 )


Не `[${p}]`работает?
Нил

@Neil Не для первого элемента каждого массива.
ETHproductions

Ах, я вижу, вы нашли обходной путь. Я дошел до a=>a.reduce((l,r)=>`${l}`.match(`[${r}]`)&&r)(который также работает для числового ввода).
Нил

Возможно, вы можете удалить, p&&если вы установите p=1/19?
Нил

@ Нейл, ну ... ну ... это гениально, спасибо :-)
ETHproductions

6

05AB1E , 10 байтов

ü‚vy`Så1åP

Попробуйте онлайн! или как тестовый набор

объяснение

ü‚          # map pairing over each pair in input
  v         # for each pair
   y`       # push as 2 separate elements on stack
     Så     # check each digit in 2nd number for membership in first
       1å   # check if any 1 exists in the resulting list
         P  # product of stack

€Sü.å- Я бы хотел, чтобы это сработало так, как я думал.
Волшебный Осьминог Урна

@carusocomputing: Да, это было бы здорово. Или просто ü.åили €Süå.
Emigna

Почему попарно не работает с точечными командами снова?
Волшебный осьминог Urn

1
@carusocomputing: он реализован только для того, чтобы принять следующий байт в качестве команды. Это не принимает во внимание точку.
Emigna

6

CJam , 18 15 14 байтов

Сохранено 4 байта благодаря Мартину Эндеру

l~Afb_1>.&:,:*

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

объяснение

l~              e# Read and eval the input
  Afb           e# Convert each number to a list of digits
     _          e# Duplicate the array
      1>        e# Slice it after the first element
        .&      e# Vectorized set intersection; take the set intersection of corresponding 
                e#  elements of the two arrays
          :,    e# Get the length of each intersection
            :*  e# Take the product of the whole array. 
                e#  Will be 0 if any intersection was empty.

6

Haskell, 51 48 35 байт

-3 байта благодаря @NickHansen! Мне действительно нужно поправиться с этими операторами монады

-4 и -9 байтов благодаря @Laikoni и @nimi соответственно!

and.(zipWith(any.flip elem)=<<tail)

Эта версия принимает входные данные в виде массива строк, что устраняет необходимость в них show, но, насколько я вижу, оно работает в основном так же, как и в старой версии:

all(\(x,y)->any(`elem`x)y).(zip=<<tail).map show

(Я вполне уверен, что мне разрешено отправлять анонимную функцию, подобную этой, но я исправлю ее при необходимости)

Сначала числа конвертируются в строки. Затем магия монад zip=<<tailсоздает функцию, которая объединяет список с самим собой, который связывает каждую запись со своими соседями. Затем allсопоставляет лямбду с каждой парой, которая проверяет, содержит ли одна строка символы из другой, и, наконец, проверяет, все ли они вышли True.

Старая версия, которая работает в основном так же:

f a=and$zipWith(\b->any(`elem`show b).show)a$tail a

Мне удалось побрить байт с помощью zip и некоторого (->) обмана монады: f (x, y) = any ('elem'x) y; g = все f. (Zip = << tail) .map show , edit: elem должен [надеюсь, очевидно] быть в кавычках, но это невозможно с помощью средства форматирования комментариев.
Ник Хансен

44 байта:and.(zipWith(any.flip elem)=<<tail).map show
Лайкони

Разрешается принимать входные данные в виде списка строк, например ["1234567890", "19", "95", "5012", "23"], так что вы можете удалить .map show.
Ними

5

Mathematica 62 47 35 байт

С сохранением 12 байтов благодаря MartinE.

FreeQ[#⋂#2&@@@Partition[#,2,1],{}]&

FreeQ[#⋂#2&@@@Partition[#,2,1],{}]&[{{1},{1,2},{2,0,3},{0},{3,1}}]

Ложь

FreeQ[#⋂#2&@@@Partition[#,2,1],{}]&[{{1},{1,2},{2,0,3},{0},{3,0}}]

Правда


4

Рубин, 49 48 байтов

->x{x.each_cons(2){|z|x&&=z*' '=~/(.).* .*\1/};x}

Вывод nilдля false и «случайное» целое для true.


4

Ява 8, 94 90 87 байт

Ввод - это массив строк, представляющих числа. Начиная со второй строки, он выполняет сравнение регулярных выражений с каждой предыдущей строкой, чтобы увидеть, содержит ли он какой-либо из своих символов:.*[previous string].* .

Golfed:

a->{int r=1,i=0;while(++i<a.length)r*=a[i].matches(".*["+a[i-1]+"].*")?1:0;return r>0;}

Ungolfed:

public class NumberChainingPredicate {

  public static void main(String[] args) {
    System.out.println("Expect true:");
    for (String[] input : new String[][] { { "1", "1", "1", "11", "111", "11", "1" }, { "12", "23", "34", "45", "56" },
        { "65", "54", "43", "32", "21" }, { "123", "29", "9", "59", "55", "52", "2017", "2" },
        { "1234567890", "19", "95", "5012", "23" } }) {
      System.out.println(java.util.Arrays.toString(input) + " = " + exec(f(), input));
    }

    System.out.println();
    System.out.println("Expect false:");
    for (String[] input : new String[][] { { "1", "2", "3", "4", "5", "1", "11" }, { "12", "23", "33", "45" },
        { "98", "87", "76", "11", "12", "23" } }) {
      System.out.println(java.util.Arrays.toString(input) + " = " + exec(f(), input));
    }
  }

  private static java.util.function.Function<String[], Boolean> f() {
    return a -> {
      int r = 1, i = 0;
      while (++i < a.length) {
        r *= a[i].matches(".*[" + a[i - 1] + "].*") ? 1 : 0;
      }
      return r > 0;
    };
  }

  private static boolean exec(java.util.function.Function<String[], Boolean> function, String[] input) {
    return function.apply(input);
  }

}

Ницца! Намного короче, чем я собирался опубликовать. В любом случае, вы можете a->{for(int i=1;i<a.length;)if(!a[i].matches(".*["+a[i++-1]+"].*"))return 0>1;return 1>0;}
Кевин Круйссен

Я также играл в гольф до 90, но по-другому:a->{int r=1;for(int i=0;++i<a.length;)r*=a[i].matches(".*["+a[i-1]+"].*")?1:0;return r>0;}
Business Cat

1
Неважно, добрался до 87:a->{int r=1,i=0;for(;++i<a.length;)r*=a[i].matches(".*["+a[i-1]+"].*")?1:0;return r>0;}
Деловой кот

Спасибо вам обоим. Я думаю, что единственный способ улучшить это на значительную величину сейчас - это посмотреть на регулярное выражение.

4

Желе , 6 байт

Dµf"ḊẠ

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

объяснение

Dµf"ḊẠ
Dµ        Treat the first (i.e. only) input as a list of decimal digits
   "      For each pair of corresponding elements in {the input digits} and
    Ḋ     {the input digits} with the first element removed
  f       take all elements common to both sides
     Ạ    then return true if the result has no empty lists, false otherwise

Это наиболее очевидно, чтобы попытаться использовать 2/здесь, но он запускает унарную функцию на всех срезах размера 2. "Ḋэффективно запускает двоичную функцию на всех парах смежных элементов, что означает, что мы можем использовать fнапрямую (вместо того, чтобы преобразовывать ее в унарный функционировать как f/). Это в конечном итоге оставляет последний элемент ввода на месте, но, к счастью, даже ввод 0 не становится пустым списком при преобразовании в десятичную, поэтому он не влияет на .




3

05AB1E , 5 байтов

Код:

üÃõå_

Использует кодировку CP-1252 . Попробуйте онлайн! или проверьте все контрольные примеры! ,

Объяснение:

üà         # Intersection on each pair
  õå       # Check if the empty string exists
    _      # Boolean negate

О человек это работает! RüÃõå_было то, что я придумал самостоятельно. Для меня большая честь быть так близко к вашему лучшему ответу, удаляя мой. Почему вам не нужно, Rхотя?
Волшебная Осьминог Урна

1
@carusocomputing Хммм, зачем Rтогда? : p
Аднан

2

PowerShell , 87 байт

param($n)(1..($a=$n.length-1)|?{[char[]]$n[($i=$_)-1]|?{$n[$i]-like"*$_*"}}).count-eq$a

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

Не самый короткий по какой-либо мере, но немного иной подход, чем другие, который демонстрирует отличную |?{}функциональность.

Это принимает входные данные в виде массива строк $n, а затем циклически переходит от 1до length-1. Мы используем Where-Object( |?{...}), чтобы вытащить те индексы, которые соответствуют действительности для конкретного условия. Вы можете думать об этом как о комбинированной forпетле сif предложением.

Пункт здесь есть [char[]]$n[($i=$_)-1]|?{$n[$i]-like"*$_*"}. То есть мы берем текущий индекс $_, устанавливаем его $iи вычитаем 1, и используем его для индексации $n(т.е. мы получаем предыдущий элемент в нашем входном массиве). Затем он приводится как char-array и отправляется через другую Where-Objectпроцедуру.

Внутреннее предложение $n[$i]-like"*$_*"указывает, что строка в текущем индексе $iявляется -likeтекущим символом$_ из предыдущего индекса. Поэтому будут выведены любые символы, которые являются общими для двух элементов массива. Таким образом, внешнее предложение будет правдивым только в том случае, если есть общий символ (поскольку в PowerShell пустой массив ложный), и поэтому индекс будет выбран только при наличии общих символов.

Затем, мы собираем все индексы , которые соответствуют критериям, и убедитесь , что .countих является -eqUAL длиной входного массива. Этот логический результат остается в конвейере, а вывод неявным.



2

APL (Dyalog APL) , 9 байтов

∧/×≢¨2∩/⎕

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

∧/ все в списке

× знаки

 из подсчета

¨ каждый из

2∩/ парные пересечения

 вход?


Я не уверен, что означают «знаки», но вы можете предположить, что все числа будут положительными.
Carcigenicate

@Carcigenicate они тоже могут быть нулевыми.
Адам

Да, прости. "Non-отрицательные".
Carcigenicate

2

PHP, 65 68

for(;null!==$a=$argv[++$i+1];)$r+=$a==strtr($a,$argv[$i],_);echo!$r;

переберите все числа и удалите все цифры, которые появились в предыдущем. Посчитайте, как часто оно совпадает с самим числом (без удаления цифры). Если хотя бы один из них равнялся, у нас не было совпадений в одной из пар.


Исправлена ​​ошибка с использованием triminsted of strtr. Благодаря @ JörgHülsermann


Большое извините. для данных тестовых случаев ваше решение работает. ["filename",1,11,414]не работает
Йорг Хюльсерманн

@ JörgHülsermann уверен, что trimработает только для начальных и конечных символов. Починил это.
Кристоф

Для PHP <7.1 вы можете использовать a&вместо null!==(-5 байт).
Титус

... но это будет работать только для первой цифры в $argv[$i], потому что "Если из и иметь разную длину, дополнительные символы в длинных из двух игнорируются". (из руководства)
Титус

2

PHP, 75 байт

for($b=3**39;--$argc;)preg_replace("#[$b]#","",$b=$argv[$argc])<$b?:die(1);

принимает числа из аргументов командной строки; 1выходить с ложью, с 0правдой.
Запустите -rили протестируйте его онлайн .

  • начать с $b= число, содержащее все цифры
  • цикл через аргументы
    • убрать все цифры $bиз аргумента
    • скопировать аргумент в $b
    • если ни одна цифра не была удалена, выйдите с 1
  • неявный: выход с 0

1

PHP, 77 байт

for($i=$t=1;++$i<$argc;)$t*=preg_match("#[{$argv[$i-1]}]#",$argv[$i]);echo$t;

1
Альтернатива: foreach($argv as$k=>$v)$t=$k--?$t*preg_match("#[{$argv[$k]}]#",$v)):1;echo$t;77 байт (не проверено).
Исмаэль Мигель

1
@IsmaelMiguel Тяжелая альтернатива Сначала вы должны перейти $k--на --$kодну и отказаться от нее ), после этого ваш подход должен сработать, и вы должны добавить @ для предупреждения
Jörg Hülsermann

О, да, я не заметил бесполезных скобок, вызывающих синтаксические ошибки. И я не согласен с этим $k--. Я специально использовал его, чтобы $ k по-прежнему равнялось 0 при первом запуске. И предупреждения игнорируются. Это означает, что код теперь составляет 76 байтов, но все еще не проверен.
Исмаэль Мигель

После редактирования могу подтвердить, что foreach($argv as$k=>$v)$t=$k--?$t*preg_match("#[{$argv[$k]}]#",$v):1;echo$t;работает как надо. Тестирование с помощью $argv = array(1, 12, 123, 3, 34, 45, 5, 5);дисплеев 1и тестирование с помощью $argv = array(1, 12, 123, 3, 34, 45, 5, 6);дисплеев0 , как и ожидалось.
Исмаэль Мигель

@IsmaelMiguel Вы забываете, что первый параметр в это имя файла.
Йорг Хюльсерманн

1

MATL , 14 байтов

1&)"V@VX&nv@]x

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

Спасибо @LuisMendo за сохранение байта. Объяснение:

1&)            % 'Pop' the first item from the input and push it on the stack.
   "       ]   % Main 'for' loop, to loop over the rest of the input.
    V            % Stringify previous (or first) iten from the input.
     @V          % Push current number, convert to string
       X&        % Intersect with stringified number already on the stack.
         nv      % Count the size of the intersection, and add it to the existing list of sizes.
           @     % Push the current number again for the intersection in the next loop. 
             x % Remove the number pushed by the last loop.
               % Else the program would end with the result on the second instead of the first position in the stack

Вы можете сохранить замену байта 1)VGна 1&)(и это позволит избежать повторения первого числа)
Луис Мендо

@ LuisMendo Конечно! Я смутно помнил, что у MATL была эта функциональность, но поиск «pop» (как в очереди или стеке) в спецификации не дал никаких результатов, поэтому я подумал, что ошибаюсь.
Sanchises

Да, на самом деле это частный случай индексации ссылок. С двумя выходами операция индексации ссылок, такая как )дает выбранные значения в качестве первого выхода, а затем оставшиеся значения в качестве второго вывода
Луис Мендо

@LuisMendo Clever. Они должны нанять вас, ребята из MATL, чтобы улучшить MATLAB ...
Sanchises

Ха - ха. Я иногда пропускаю некоторые из этих функций в MATLAB
Луис Мендо,

1

Clojure, 71 байт

(fn[n](every?(fn[[q w]](some q w))(partition 2 1(map #(set(str %))n))))

Анонимная функция, которая принимает последовательность чисел. Возвращает true/ false.

Мне нравится, как это читается. Здесь определенно есть несколько областей, которые можно улучшить. Моя функция передаетсяmap не может быть легко изменена, так что для нее не требуется макрос функции, что означает, что вся функция не может использовать макрос, который, вероятно, добавил несколько байтов. Также было бы хорошо, если бы я мог найти лучший способ распаковки значений в every?предикате.

(defn number-chain? [nums]
  (let [; Turn each number into a set of characters
        set-nums (map #(set (str %)) nums)

        ; Partition the sets into lists of neighbors
        ; [1 2 3 4] -> [[1 2] [2 3] [3 4]]
        partitioned (partition 2 1 set-nums)]

    ; Does every second neighbor contain some element of the first?
    (every?
      (fn [[l1 l2]]
        (some l1 l2))
      partitioned)))

1

SimpleTemplate, 124 байта

Вау, это была тренировка!

{@eachargv asA keyK}{@ifK}{@setR"/[",O,"]/"}{@calljoin intoR"",R}{@ifA is notmatchesR}{@return}{@/}{@/}{@setO A}{@/}{@echo1}

Это «просто» делает регулярное выражение, используя старый элемент, показывая 1 как истинное значение, или ничего другого.


Ungolfed:

{@each argv as number key K}
    {@if K}
        {@set regex "/[", old, "]/"}
        {@call join into regex "", regex}
        {@if number is not matches regex}
            {@return false}
        {@/}
    {@/}
    {@set old number}
{@/}
{@echo 1}

1

JavaScript (ES6), 37 байт

s=>/^(.*(.).*\n(?=.*\2))+.+$/.test(s)

Принимает ввод как строку разделенных новой строкой чисел. Основано на превосходном ответе Retina @ MartinEnder, но выполняет весь тест в одном регулярном выражении, потому что в этом случае он короче в JavaScript.


1

зернышко , 12 10 байт

$&B@X^_MPg

Принимает ввод как последовательность аргументов командной строки. Вывод - непустой список для правды и пустой список для фалси.Попробуйте онлайн или проверьте все контрольные примеры .

объяснение

         g  List of all cmdline args
       MP   Map this function to consecutive pairs of items from that list:
     ^_      Split 1st item of pair into list of characters
    X        Convert to regex that matches any of those characters
  B@         Find all matches in 2nd item of pair
$&          Fold on logical AND--truthy if all items are truthy, falsey if one is falsey
            Print (implicit)

1

Röda , 45 35 байт

{[_=~`(\S*(\S)\S* (?=\S*\2))+\S+`]}

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

Это похоже на решение Perl 5, которое является портом решения Retina от Martin Ender. -10 байт благодаря @Neil.

Вот другое решение ( 73 72 байта):

{[_/""]|{|x|{x|[0]()unless[not(_ in y)]else[1]}if tryPeek y}_|sum|[_=0]}

Это анонимная функция, которая извлекает строки из потока и проверяет, что последовательные строки содержат одинаковые символы. Объяснение:

{
    [_/""]|    /* split strings -> creates arrays of characters */
    {|x|       /* begin for loop over character arrays */
        {      /* begin if tryPeek(y) -> peeks the second item from the stream */
               /* x and y are now two consecutive character arrays */
            x| /* push characters in x to the stream */
            [0]()unless[not(_ in y)]else[1] /* pushes 0 to the stream */
                                            /* if y contains the character */
                                            /* in the stream, otherwise 1 */
        }if tryPeek y
    }_|        /* end for loop */
    sum|       /* sum all numbers in the stream */
    [_=0]      /* return true if the sum is zero */
}

Это может быть в гольф больше ...


Поможет ли это иметь одно регулярное выражение, которое выполняет весь тест за один раз? Нечто подобное ^(\S*(\S)\S* (?=\S*\2))+\S+$.
Нил

@Neil Это похоже на работу. Благодарность!
fergusq

1

Утилиты Bash + Unix, 71 69 байт

sed "s/\(.*\)/<<<\1 \&\&grepx[\1]/;1s/.*g/g/;\$s/ .*//"|tr 'x
' \ |sh

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

Ввод на стандартный ввод, один номер в строке.

Выход находится в коде выхода: 0 для правды, 1 для фальси.

Это, вероятно, может быть в гольф больше.

Чтобы приведенный выше код работал, в текущем каталоге не может быть ни одного файла, имя которого состоит из одной цифры. Если это не приемлемо, замените [\1]в программе'[\1]' (стоимостью 2 дополнительных байта).

Пробный прогон (последний тестовый пример, представленный в задании):

$ echo '98
> 87
> 76
> 11
> 12
> 23' | ./digittest > /dev/null; echo $?
1

(1 вот фальси.)


Как это работает:

Я продемонстрирую на примере выше.

Команда sed преобразует ввод в:

grepx[98]
<<<87 &&grepx[87]
<<<76 &&grepx[76]
<<<11 &&grepx[11]
<<<12 &&grepx[12]
<<<23

Команда tr затем преобразует это в строку:

grep [98] <<<87 &&grep [87] <<<76 &&grep [76] <<<11 &&grep [11] <<<12 &&grep [12] <<<23

Эта строка является командой оболочки для выполнения желаемой операции, поэтому я передаю ее в sh и все готово.


Ограничение на файл в порядке, хотя это, конечно, странное ограничение.
карцигеникат

1

Q, 57 байт

{r::();({r,::any(last x)in y;x,enlist y}\)($)0,x;all 1_r}
  1. Инициализирует глобальный р.
  2. Преобразует ввод в массив строк.
  3. Сканирует массив, проверяя, находится ли какой-либо символ в последней строке в текущей строке.
  4. Добавляет каждый результат к r.
  5. Возвращает 1, если все строки удовлетворяют шагу 3, иначе возвращает 0.

Примечание: 0 добавляется к началу входного массива внутри функции. Это было сделано для того, чтобы сравнение по первому элементу было сделано зачислено. В противном случае последний символ первого элемента будет выбран для сравнения. Однако можно выполнить проверку типа, которая добавляет 7 байтов к текущему количеству.


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