Enklactify эти строки


42

Вдохновленный этой цепочкой комментариев ...

Я хочу enklactвыйти из этого испытания, но я не могу ...

@ETHproductions to enklact (v): реализовать таблицу поиска, используя подраздел, состоящий из уникальных элементов.


Включение - очень полезный способ сжатия таблицы поиска. Например, допустим, у вас был следующий список цветов:

red
green
blue
yellow
purple
orange

Если вы хотите иметь возможность принимать цвет в качестве входных данных и возвращать его индекс в этом списке, очевидно, существует простой способ:

["red", "green", "blue", "yellow", "purple", "orange"].index(input())

Но есть способ, которым мы могли бы сделать это меньше байтов:

"rgbypo".index(input()[0])

Это работает, потому что первый (или 0-й) индекс каждой строки уникален. Этот пример очевиден, но иногда он немного сложнее. Что если мы хотим создать таблицу поиска для этого списка?

Sweet Onion Chicken Teriyaki
Oven Roasted Chicken
Turkey Breast
Italian BMT
Tuna
Black Forest Ham
Meatball Marinara

В этом случае мы не можем сделать это:

"SOTITBM".index(input()[0])

потому что есть два различных ввода, которые начинаются с 'T', а именно, "Тунец" и "Турция". Мы должны посмотреть на другой индекс. Если вы посмотрите на 4-й индекс каждой строки, вы заметите, что все они уникальны. Таким образом, мы можем сделать это ...

"enklact".index(input()[3])

В этом случае «строка enklaction» - это «enklact».

Это приводит нас к сегодняшнему вызову ...

Получив список строк, верните любую допустимую строку включения. Или, другими словами, при наличии списка строк возвращать любую новую строку, где каждая буква уникальна, и строка формируется путем соединения i-й буквы каждой строки.

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

Каждая строка будет содержать только печатный ASCII, и эта проблема чувствительна к регистру.

Это , поэтому постарайтесь написать самую короткую программу на вашем языке!

Контрольные примеры

Input:
Programming
Puzzles
Code
Golf

Output (any one of these):
"ozdl"
"gzef"


Input:
the quick
brown fox
jumped over
lazy dogs

Output:
"tbjl"
"hrua"
"eomz"
" wpy"
"qne "
"if o"
"kxvs"

Note that "u dd" and "coog" are not valid.


Input:
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

Output:
""


Input:
AbC
aBc
bbC

Output:
"Aab"


Input:
@#$%^_
Hello_World
How are you?

Output:
"#eo"
"$lw"
"%l "
"^oa"


Input:
a
ab
ac

Output:
""

Можем ли мы вернуть список допустимых строк?
LyricLy

@ LyricLy Хм, теперь, когда я думаю об этом, это имело бы больше смысла. Но так как ответы уже есть, и не так уж много, чтобы вернуть первый, я собираюсь сказать нет, это должна быть любая допустимая строка.
DJMcMayhem

Можем ли мы гарантировать, что ни одна из введенных строк не будет пустой?
musicman523

6
Может ли постоянное ложное значение быть ошибкой согласованного типа?
Стьюи Гриффин

2
Извините, но я думаю, что правильный глагол enklactate .
Эрик Outgolfer

Ответы:


8

Python3, 59 байт

lambda l:{len({*d}):''.join(d)for d in zip(*l)}.get(len(l))

Возвращает строку с enklact, в противном случае None


8

Python 2 , 68 67 61 байт

lambda a:`{0:j for j in zip(*a)if len(set(j))==len(j)}`[6::5]

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

улучшения


Если вывод не должен быть строкой:

Python 3 , 49 байт

lambda a:[j for j in zip(*a)if len({*j})==len(j)]

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



@JoKing Элегантно и реализовано.
Нил

Я думаю max(`j`[2::5]for j in[""]+zip(*a)if len(set(j))==len(j)), что работает, чтобы сохранить байт.
Линн

@ Линн спасибо и обновил.
Нил

7

Retina , 43 32 байта

+/^(.).+^\1|^$/ms&m`^.

|""Lm`^.

Попробуйте онлайн! Изменить: Сохранено 11 байтов благодаря @MartinEnder. Объяснение:

+

Повторите, пока изменяется вход ...

/^(.).+^\1|^$/ms&

... только если одна строка пуста или две строки начинаются с одного и того же символа ...

m`^.

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

|""L`^.

Соберите первый символ каждой строки. (Если решения не было, вышеприведенный цикл удалит все, и собирать будет нечего.)


Параметры регулярного выражения также принимают модификаторы регулярного выражения (записывая их непосредственно после закрывающего разделителя): tio.run/##K0otycxLNPz/…
Martin Ender

На самом деле, это позволяет полностью избавиться от второго этапа: tio.run/##K0otycxLNPz/X1s/… (как-то здесь нельзя применить mгруппу, похоже, что условный этап не распространяет параметр).
Мартин Эндер

Ах, конечно, цикл условный вместо условного цикла, который решает ошибку бесконечного цикла в вашей первой версии. Очень аккуратный!
Нил

5

Haskell , 71 байт

f x|elem""x=""|y<-head<$>x,and[filter(==a)y==[a]|a<-y]=y|1<2=f$tail<$>x

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

BMO сохранил 3 байта с помощью any null xelem""x.

Эрджан Йохансен сохранил байт с помощью sum[1|b<-y,a==b]<2filter(==a)[y]==[a].

объяснение

f x|elem""x=""                      -- Once any of the strings is empty, return "".
   |y<-head<$>x                     -- Otherwise, let y be all the first letters...
   ,and[                 |a<-y]     -- If, for all a in y,
        filter(==a)y==[a]           -- a occurs just once in y:
                               =y   -- return y.
   |1<2=f$tail<$>x                  -- Else, chop off all the first letters and recurse.

Если выдает ошибку ( Prelude.head: empty list), когда нет решения, все в порядке, |elem""x=""может быть стерто за 61 байт .


1
Краткий тест:filter(==a)y==[a]
Орджан Йохансен

4

Рубин , 38 байт

->x,*y{x.zip(*y).find{|z|z==z-[p]|[]}}

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

Спасибо ГБ за указание на ошибку.


Сбой, если совпадения нет и первая строка не самая короткая.
ГБ,

@ GB Не могли бы вы привести пример? Я изменил свой последний тест в соответствии с вашим описанием, и это сработало.
Кирилл Л.

Попробуйте ["abc", "ac", "acd"]
GB

Теперь я вижу, ты прав. Должно быть исправлено.
Кирилл Л.

4

Pyth , 6 байт

>1{I#C

Тестирование.

Вывод представляет собой одноэлементный список, как это разрешено по умолчанию ; list [] (пустой список, ложь) возвращается, если строка не может быть объявлена .

объяснение

> 1 {I # C - Полная программа.
     C - Транспонировать ввод, обрезая отсутствие.
    # - Сортировать по:
  {Я - Инвариант при дедупликации.
> 1 - Разрезать до 1. list [: 1] в Python.

Pyth , 5 байт

Это было бы правильно, если бы сбой считался ложным значением.

h{I#C

Тестирование.


3

Haskell , 76 74 байта

f t=last$"":(id=<<foldr(zipWith(#))([[]]<$t)t)
x#[s]=[x:s|all(/=x)s]
x#e=e

Попробуйте онлайн! Возвращает последнюю действительную строку поиска или пустую строку, если такой строки не существует.


71 69 байт

Если допускается создание согласованного исключения в качестве ложного значения:

f t=head$id=<<foldr(zipWith(#))([[]]<$t)t
x#[s]=[x:s|all(/=x)s]
x#e=e

Попробуйте онлайн! Выдает empty listисключение, если строка не найдена, в противном случае возвращает первую допустимую строку.

-2 байта благодаря Орджану Йохансену


1
notElem x можно сократить до all(/=x).
Орджан Йохансен

2

Желе , 7 байт

z0Q€fZḢ

Возвращает целое число 0, если строки не могут быть инклацифицированы.

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

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

z0Q€fZḢ  Main link. Argument: A (string array)

z0       Zip/transpose, filling shorter rows with 0.
  Q€     Unique each deduplicate resulting string.
     Z   Zip/transpose, without using a filler.
    f    Filter; keep only string that appear in the results to both sides.
      Ḣ  Head; extract the first string. Returns 0 if the array is empty.


2

Stax , 9 8 байт

åτIⁿs↓µg

Запустите и отладьте его

Объяснение (без упаковки):

M{c0-u=}j Full program, implicit input
          e.g. ["Programming", "Puzzles", "Code", "Golf"]
M         Transpose
                ["PPCG", "ruoo", "ozdl", "gzef", "rl\0\0", "ae\0\0", "ms\0\0", "m\0\0\0", "i\0\0\0", "n\0\0\0", "g\0\0\0"]
 {     }j Find first matching element:
            e.g. "PPCG"
  c0-       Copy and remove zero bytes (padding)
                 "PPCG" "PPCG"
     u      Unique
                 "PPCG" "PCG"
      =     Check if equal:
                 1
          First matching here: "ozdl". If none is found, the stack is empty
          Implicit output if anything on stack

2

R , 127 байт

function(S,s=sapply(S,substring,x<-1:max(nchar(S)+1),x))cat(rbind(s[!apply(s,1,anyDuplicated)&!rowSums(s==""),],"")[1,],sep="")

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

sapplyобычно возвращает a, matrixкогда все length(FUN(X[[i]]))равны, кроме когда length(FUN(X[[i]]))==1, и в этом случае он возвращает a vector. Для того, чтобы использовать матричные операции, нам нужно еще на substringодин шаг больше, чем нам нужно, чтобы гарантировать a matrix, поэтому он xраспространяется на max(nchar(S)+1).

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

Затем мы печатаем enklactстроку ified или пустую строку.


2

R , 116 107 95 байт

R + pryr

pryr::f(for(i in 1:min(nchar(v)))`if`(anyDuplicated(t<-substr(v,i,i)),0,{cat(t,sep="")
break}))

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

база R

function(v)for(i in 1:min(nchar(v)))`if`(anyDuplicated(t<-substr(v,i,i)),0,{cat(t,sep="")
v=0})

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

Эти два варианта экономят 9 байтов благодаря Giuseppe .

Объяснение:

Это эффективно усекает все строки в векторе vдо длины самого короткого и повторяет последующие индексы. Затем проверяет, есть ли какие-либо дубликаты внутри выбранных букв, а если нет, вставляет их вместе и печатает с помощью cat. Если все индексы возвращают дублированные результаты, это печатает пустую строку.
Все они заключены в анонимную pryrфункцию, breakчтобы остановить цикл, или базовую функцию R, обнуляющую вектор, чтобы разорвать цикл.


1
Хороший! Это может быть golfed до 107 байтов в R+pryrили 107 байтов в базовой R.
Giuseppe

2

Japt, 9 байт

Принимает ввод как массив символьных массивов, возвращает массив символов или undefined

y æ_f eZâ

Попробуйте это (добавьте новую строку в начале программы с кодом, qR mqчтобы принять ввод в виде строки, разделенной новой строкой, чтобы избавить вас от необходимости создавать массивы.)


объяснение

y             :Transpose
  æ_          :Pass each array Z through a function and return the first that returns true
    f         :  Filter nulls (used for padding when transposing)
      e       :  Test for equality with
       Zâ     :  Z deduplicated

Я попробовал вызов перед чтением вашего решения и получил почти идентичное решение:z æ_¬eZ¬â
Nit

Точно такой же, кроме формата ввода.
Лохматый


1

Python 3 , 75 байт

def f(t):c=[s.pop(0)for s in t];return all(t)and(f(t),c)[len(t)==len({*c})]

Работает со списками символов вместо строк. Возвращает False, если не существует допустимой строки включения.

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


Я думаю, что это повторяется, что сделало бы его недействительным, если он не f=включен в число байтов.
LyricLy

@LyricLy Исправлено :)
musicman523

1

C (gcc) , 161 байт

f(s,i)char**s;{char**t,a[255],*u=a;for(i=0;memset(a,0,255),u&&~i;i+=!!~i&&u)for(t=s;(u=u?*t++:0)&&~(i=u[i]?i:-1)&&!a[u[i]]++;);while(~i&&(u=*s++))putchar(u[i]);}

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

Каждая позиция символа проверяется на дублирование и пропускается, если дубликат обнаружен; это продолжается до тех пор, пока не закончится самая короткая строка. К сожалению, это только ASCII: строки DBCS / UTF-8 сильно нарушают эту функцию!



1

Japt , 12 байт

Возвращает undefinedдля не энклактических строк.

y ·æ_¬n ä¦ e

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

Объяснение:

y ·æ_¬n ä¦ e
y             // Split the input at newlines and transpose
  ·           // Join on newlines 
   æ_         // Return the first item that returns truthy when ran through:
     ¬n       //   Sort
        ä¦    //   Reduce with !=
           e  //   All items are truthy (unique)

Вы должны быть в состоянии сохранить 2 байта, взяв входные данные в виде массива символьных массивов и разделив их на два split.
Лохматый

1

Wolfram Language (Mathematica) , 54 байта

#&@@Select[PadRight@#,#~FreeQ~0&&Union@#==Sort@#&]&

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

Принимает список символов в качестве входных данных, возвращает список символов. Содержит U + F3C7, соответствующий оператору «Transpose».

Возвращает #1и выбрасывает кучу игнорируемых ошибок, когда подходящей строки нет.

Объяснение:

PadRight@#

Дополните ввод так, чтобы каждая «строка» (список символов) была одинаковой длины. Это добавляет целое число 0s (не строка "0"s). Тогда перенести.

Select[ ... ,#~FreeQ~0&&Union@#==Sort@#&]

Выберите строки, в которых нет целых чисел 0s и которые содержат все уникальные символы.

#&@@

Получи первый.


1

JavaScript (ES6), 66 байт

Возвращает либо строку, либо, undefinedесли решение не существует.

f=(a,i=0)=>a.every(s=>(o[k+=c=s[i],c]^=1)&&c,o=k=[])?k:c&&f(a,i+1)

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

комментарии

f = (           // f = recursive function taking:
  a,            //   a[] = input array
  i = 0         //   i   = pointer
) =>            //
  a.every(s =>  // for each string s in a[]:
    (o[k +=     //   append to the key string k
      c = s[i], //   the character c at position i in s
      c] ^= 1   //   and toggle o[c] (undefined -> 1 -> 0)
    ) && c,     //   additionally, make sure that c is defined
    o = k = []  //   start with o = k = empty array
  ) ?           // every() is true if all characters were distinct and defined:
    k           //   in which case we return k
  :             // else:
    c &&        //   provided that every() didn't fail because of an undefined character,
    f(a, i + 1) //   try again at the next position

1

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

-2 байта благодаря @Neil !

§ΦE⌊EθLι⭆θ§λι⬤ι⁼¹№ιλ⁰

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


Да, когда а) qперестал всегда быть строкой б) StringMap начал работать на не-строки? В любом случае, ваш Rangeненужный, экономя 2 байта.
Нил

@Neil а) Когда я добавил массив / объект ввода b)> _> Я не уверен. вероятно, примерно в то время, когда я исправил цикл while (извините, я не упомянул ни одного из них)
только ASCII

1

Шелуха , 9 байт

ḟS=UḞz:∞ø

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

объяснение

fS=UḞz:∞ø
    Ḟz:∞ø  Transpose the input dropping characters of longer strings
    Ḟ        Fold right
     z:      Zip with prepend
       ∞ø    Infinite list of empty lists
ḟS=U       Find the first string without duplicates, returns an empty string if none
ḟ            Return first value satisfying predicate
  =          Equal
 S U         to itself with duplicates removed

Использование ←ġLTover Ḟz:∞øдолжно сохранить байт.
ბიმო

1

Сетчатка , 81 56 байт

m`$
$.=*£¢
N$`.
$.%`
¶

~`(.*?¢)+
L`.{$#1}
A`(.).*\1|£|¢

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

-25 байт благодаря @Neil


Транспонировать прямоугольный текст в Retina на удивление сложно.


Хотелось бы, чтобы я знал лучший способ выполнения прямоугольной транспонирования, но в то же время сэкономил 25 байтов .
Нил

@ Нил Ааа ... Эваль. Я всегда забываю, что в Retina 1.0 есть все эти новые интересные функции
TwiNight,

1

Perl 6 , 27 байт

{([Z] $_).first:{.Set==$_}}

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

Увидев, что версия ruby ​​была отклонена, я скопировал подход и использовал списки символов вместо строк. Мне это не нравится

Моя более старая и более правильная подача приведена ниже:

Perl 6 , 38 байт

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

{[~] ([Z] @_>>.comb).first:{.Set==$_}}

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


1

C (gcc) , 121 113 110 байт

i;d;f(s)char**s;{char**_=s,x[255]={0},y[99]={0};for(d=i=0;*_;)d+=x[y[i++]=*(*_++)++]++;d=d?*x?0:f(s):puts(y);}

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

Ungolfed

void enklactify(char *strings[]) {
    int quit = 0;
    while (!quit) {
        char **arg = strings;      // current row
        int exists[255] = {0};     // which characters exist in the column
        char output[99] = {0};     // will hold output string
        int index = 0;             // where to insert in output
        int duplicates = 0;        // have we found any duplicates?
        while (*arg != NULL) {
            char *word = *arg;     // current word
            char first = *word;    // first letter of current word
            if (exists[first])
                duplicates = 1;    // we found a duplicate
            exists[first] = 1;     // mark it as in our string
            output[index] = first; // add it to our output
            index++;
            (*arg)++;              // advances the current word to the next
                                   // character by reference (chops first char)
            arg++;                 // advance to next whole argument
        }

        if (!duplicates) {         // This is a valid solution
            puts(output);
            quit = 1;
        }

        if (exists[0]) {           // We hit the null terminator of one of the
                                   // input strings, so we failed
            quit = 1;
        }
    }
}

-3 благодаря потолку

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

  • d+=x[y[i++]=*(*_)++]++который добавляет первый символ первой строки _к y, продвигает первую строку, _чтобы удалить свой первый символ, добавляет xзапись с этим символом dи увеличивает эту xзапись
  • q=d?*x:puts(y)который печатает, yесли dне равен нулю при установке qна ненулевое значение, или устанавливается qна ненулевое значение, если первый элемент xненулевой (если бы мы были в конце одной из строк, то указанный элемент был бы ненулевым нуль)

Редактировать: побрить байты, переключаясь из цикла while в рекурсивный вызов хвоста и удаляя скобки из цикла for.


Предлагаю for(d=i=0;*_;)вместо for(d=0,i=0;*_;++_)и *(*_++)++]++;d=d?!*x*f(s)вместо*(*_)++]++;d=d?*x?0:f(s)
потолок кошка

0

Pyth, 13 байт

e+kf{IT@.TQ.t

Попробуй здесь

e+kf{IT@.TQ.t
           .tQ   Transpose the (implicit) input with padding.
        .TQ      Transpose the input without padding.
       @         Take the strings in both.
   f{IT          Find the ones that have no duplicates.
e+k              Get the last, or an empty string.

1
Кажется, что возвращение списка всех допустимых строк недопустимо.
LyricLy

@LyricLy Исправлено.
Мнемоника

0

Красный , 139 байт

func[b][m: length? first b foreach a b[m: min m length? a]repeat n m[c: copy[]foreach a b[append c a/(n)]if c = unique c[return rejoin c]]]

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

Объяснение:

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

f: func[b][
    m: length? first b                   ; the minimal length of the first string  
    foreach a b[m: min m length? a]      ; find the minimal length of all strings
    repeat n m[                          ; limit the search to the minimal length
        c: copy[]                        ; an empty block  
        foreach a b[append c a/(n)]      ; for each string append the current char
        if c = unique c[return rejoin c] ; if all chars are unique, return the block
    ]  
]

0

Röda , 80 77 байт

f a{a|seq 0,#_|try{{|i|a|[_[i:i+1]]|orderedUniq|concat|[_]if[#_1=#a]}_|head}}

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

-1 байт благодаря шарлатану коров

Объяснение:

f a{
  a|         /* Push the strings in a to the stream */
             /* For each string (_): */
  seq 0,#_|     /* Push a range from 0 to the length of _ to the stream */
  try{       /* Ignore errors during the following block */
    {|i|        /* For each i in the stream: */
      a|           /* Push strings in a to the stream */
      [_[i:i+1]]|  /* For each string, push the ith character to the stream */
      orderedUniq| /* Remove duplicate characters */
      concat|      /* Join the characters into a string */
      [_]if        /* Push the string to the stream if */
      [#_1=#a]     /* Its length is the length of a */
    }_|
    head        /* Take the first string in the stream and return it */
  }
}

tryИспользуется ключевое слово , чтобы отклонить ошибки , которые возникают , если iбольше , чем длина самой маленькой строки в a, или нет ответа и headвызывает ошибку.


Вы можете удалить парены, seqчтобы сохранить байт
Kritixi Lithos

@ Cowsquack Спасибо!
fergusq

0

Java 10, 106 байт

a->{for(int i=0;;i++){var r="";for(var s:a)r+=s[i];if(r.length()==r.chars().distinct().count())return r;}}

Выдает ошибку вместо возврата пустой строки, если решение не может быть найдено. Ввод - это символьная матрица.

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

Объяснение:

a->{                  // Method with character-matrix parameter and String return-type
  for(int i=0;;i++){  //  Loop `i` upwards
    var r="";         //   Result-String, starting empty
    for(var s:a)      //   Loop over the character-arrays of the input
      r+=s[i];        //    And append every `i`'th character to `r`
    if(r.length()==r.chars().distinct().count())
                      //   If `r` only contains unique characters
      return r;}}     //    Return `r` as result

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

0

Clojure, 59 байт

#(for[s(apply map list %):when(=(count(set s))(count %))]s)

Возвращает список списков персонажей.


0

APL + WIN, 35 33 байта

2 байта сохранены благодаря Адаму

Запрашивает строки текста в виде символьной матрицы:

⊃((↑⍴¨a)=+/¨((a⍳¨a)=⍳¨⍴¨a))/a←,⌿⎕

Попробуйте онлайн! Предоставлено Dyalog Classic

Объяснение:

a←,⌿⎕ prompts for input and creates a nested vector of the input matrix columns

((a⍳¨a)=⍳¨⍴¨a) creates a binary vector for each nested element with a 1 for each unique element

((↑⍴¨a)=+/¨ sums each binary vector and compares to number of characters in each element

(...)/a←⊂[1]⎕ selects only those elements where number of uniques = column length

⊃ converts nested vector back to a matrix of each valid enklaction string 

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