Найдите иголку в стоге сена


38

Учитывая прямоугольный стог сена размером не менее 2x2, состоящий из всех одинаковых печатаемых символов ASCII, выведите местоположение (считая от верхнего левого угла) иглы, которая является другим символом.

Например, если введен следующий стог сена:

#####
###N#
#####
#####

Выходные данные должны быть 3,1при нулевой индексации (что я буду использовать в этой задаче) или 4,2при одной индексации.

Стог сена может состоять из любого печатного символа ASCII:

^^^
^^^
^N^
^^^
^^^
^^^

выход: 1,2

и иглой будет любой другой печатный символ ASCII:

jjjjjj
j@jjjj
jjjjjj

выход 1,1

Также возможно иметь иглу в углу:

Z8
88

выход 0,0

88
8Z

выход 1,1

или иметь иглу на краю:

>>>>>>>>>>
>>>>>>>>>:
>>>>>>>>>>

выход 9,1

Правила и разъяснения

  • Вход и выход могут быть заданы любым удобным способом . Это означает, что вы можете воспринимать ввод как список символов, одну строку и т. Д.
  • Вы можете распечатать результат в STDOUT или вернуть его как результат функции. Пожалуйста, укажите в своем представлении, в каком порядке выводится результат (т. Е. Горизонтальный, а затем вертикальный, как используется в задании, или наоборот).
  • Допустимы либо полная программа, либо функция.
  • Вы не можете выбрать, какие символы использовать. Это проблема.
  • Стог сена гарантированно будет размером не менее 2х2, так что однозначно, какая игла, а какая - сено.
  • На входе присутствует только одна игла, и ее размер равен одному символу.
  • Стандартные лазейки запрещены.
  • Это поэтому применяются все обычные правила игры в гольф, и выигрывает самый короткий код (в байтах).

Предлагаемый тестовый пример: 88\n8Z(с любыми двумя символами, конечно).
Кевин Круйссен

Можем ли мы принять входные данные как многомерный массив? т.е. [['#', '#', '#', '#', '#'], ['#', '#', '#', 'N', '#'], ['#' , '#', '#', '#', '#'], ['#', '#', '#', '#', '#']];
640 КБ

2
@gwaugh Понравился список персонажей? Да, это нормально (и явно вызвано как ОК).
AdmBorkBork

3
Можем ли мы принять входные данные в виде пары строк без перевода строки и ширины (или высоты) стога сена? то есть("########N###########", 5)
мое местоимение monicareinstate

3
@ Someone Да, хотя у него нет реального кворума , я чувствую, что это должно быть разрешено.
AdmBorkBork

Ответы:


17

R , 49 47 44 байтов

function(m,`?`=which)m==names(?table(m)<2)?T

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

Принимает ввод как матрицу, возвращает 1-индексированные координаты


4
Это whichназначение позорно гладко.
Преступно-

4
Я был так взволнован, чтобы попробовать этот вызов в R, затем я увидел это и решил вместо этого плакать от страха
Sumner18

9

Perl 6 ,41 38 37 байт

3 байта сохранены благодаря @nwellnhof.

1 байт сохранен благодаря Джо Кингу.

{map {[+] ^∞Z*!<<.&[Z~~]},$_,.&[Z]}

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

объяснение

Он принимает входные данные в виде списка списков символов и возвращает список длиной 2, содержащий основанные на нуле координаты X и Y стрелки.

Он работает, применяя блок {[+] ^∞ Z* !<<.&[Z~~]}на входе и его транспонирования. .&[Z~~]проходит через все столбцы аргумента и возвращает, Trueесли все элементы одинаковы, в Falseпротивном случае. Затем мы отменяем все значения (поэтому у нас есть список с одним bool на столбец, где bool отвечает на вопрос «находится ли стрелка в этом столбце?»), Умножаем их поэлементно на последовательность 0,1,2 ,. .. ( True = 1и False = 0) и суммируем список, поэтому результатом всего блока является номер столбца, в котором была найдена игла, на основе 0.

Лучший подход Nwellnhof, Perl 6 , 34 байта

{map *.first(:k,*.Set>1),.&[Z],$_}

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

объяснение

Вообще такой же подход, просто более эффективный. Он по-прежнему использует блок массива и его транспонирование, но теперь блок преобразует все строки в Setsи проверяет количество элементов. Затем firstфункция выдает индекс (из-за :k) первой строки, которая содержит более 1 элемента. Из-за этого порядок $_и .&[Z]нужно было поменять местами.


Хороший подход! 34 байта с first(:k), Setи .&[Z].
nwellnhof

@nwellnhof, очень хорошо сделано. Вы в основном нашли то, что я хотел найти, но не смогли этого сделать :—). (Также я понятия не имел, что вы могли бы написать .&[Z].)
Рамилли

В общем, .&[op]не похоже, [op] $_но это работает Zпо какой-то причине.
nwellnhof

@ Шучу, спасибо!
Рамили

9

Python 2 , 57 байт

lambda m:[map(len,map(set,a)).index(2)for a in zip(*m),m]

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


Порт этого для Python 3 может быть 62 байта :

lambda m:[[len(set(v))for v in a].index(2)for a in(zip(*m),m)]

Понимание списка [len(set(v))for v in a]теперь короче двойной карты на два байта, так как его нужно будет привести к списку, подобномуlist(map(len,map(set,a)))

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


6

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

c≡ᵍ∋Ȯ&;I∋₎;J∋₎gȮ∧I;J

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

Выходы [I,J], где Iнаходится индекс строки и индекс Jстолбца, оба с 0 индексами.

Глупо долго, но получение индексов в брахилоге обычно очень многословно.

объяснение

c                       Concatenate the Input into a single string
 ≡ᵍ                     Group identical characters together
   ∋Ȯ                   Ȯ is a list of One element, which is the needle character
     &;I∋₎              Take the Ith row of the Input
          ;J∋₎          Take the Jth character of the Ith row
              gȮ        That character, when wrapped in a list, is Ȯ
                ∧I;J    The output is the list [I,J]

6

PHP ,99 85 байт

Использование строки без перевода строки и ширины (или высоты ('########N###########', 5) в качестве ввода.

  • -5 байт, удалив вызов chr (), реквизит @Titus
  • -9 байтов, принимая входные данные как два аргумента функции, также поддерживает @Titus
function($a,$l){return[($p=strpos($a,array_flip(count_chars($a,1))[1]))%$l,$p/$l|0];}

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

Ungolfed:

function need_hay( $a, $l ) {

    // identify the "needle" by counting the chars and 
    // looking for the char with exactly 1 occurrence
    // note: this is 1 byte shorter than using array_search()
    $n = array_flip( count_chars( $a, 1 ) )[1];

    // find the location in the input string
    $p = strpos( $a, $n );

    // row is location divided by row length, rounded down
    $r = floor( $p / $l );

    // column is remainder of location divided by row length
    $c = $p % $l;

    return array( $c, $r );

}

Выход:

#####
###N#
#####
#####
[3,1]

^^^
^^^
^N^
^^^
^^^
^^^
[1,2]

jjjjjj
j@jjjj
jjjjjj
[1,1]

1
1) нет необходимости chr: если вторым параметром для strpos является целое число, он будет интерпретирован как код ASCII. -> -5 байт. 2) Два функциональных параметра $s,$wмогут сохранить еще 9 байтов.
Тит

@ Titus, удаляя chr (), это замечательно. Спасибо! Функциональные параметры мне тоже приходили в голову, я просто не хотел проверять входные требования. Я уточню с ОП.
640KB

5

05AB1E , 9 6 байтов

Сохранено 3 байта переключения формата ввода.

Ввод принимается как строка и длина строки.
Выход - это нулевой список в форме[y, x]

D.mks‰

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

объяснение

D           # duplicate the input string
 .m         # get the least frequent character
   k        # get its index in the string
    s       # swap the row length to the top of the stack
     ‰      # divmod the index of the least frequent char with the row length

Черт, ты меня побил. Работал над ответом. Только что закончил 13-байтовый. Но твой путь намного лучше, так что +1 вместо этого. :) Полностью забыли про .m..
Кевин Круйссен

@KevinCruijssen: Да. Я не думаю, что когда-либо использовал .mраньше, но я был достаточно уверен, что видел это в некоторый момент :)
Emigna

5

Python 3 + NumPy , 75 66 байт

-9 байт благодаря @ ASCII-only

lambda x:where(x.view('i')-median(x.view('i')))
from numpy import*

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

Это предполагает, что входные данные являются массивом NumPy. Выходные данные индексируются с нуля, и сначала вертикальный, а затем горизонтальный.

Он преобразует входные данные из charв, а intзатем вычисляет медиану массива, который будет символом стога сена. Мы вычитаем это из массива, что делает иглу единственным ненулевым элементом. Наконец, верните индекс этого элемента с помощью numpy.where().


1
Поскольку вы знаете, что вход будет ASCII (т.е. помещается в байт), почему бы не использовать его uint8на один байт меньше?
Драконис

1
Язык должен быть "Python 3 + numpy" здесь, так как numpy не включен в нормальный дистрибутив Python
только ASCII

@Draconis это был мой план, но он вводил нули между правильными uint8ASCII-кодами. Я предполагаю, что это потому, что Python3 использует Unicode в качестве стандартного формата ввода для строк.
hbaderts


1
Это хорошо, в конце концов, это не только основано на вашем решении, но и я все равно обычно не использую numpy. Кроме того, в любом случае неизбежно, что решение может быть очень похожим, учитывая, что все решения являются общедоступными, и это сравнительно простая задача
только ASCII

4

Желе , 5 байт

Выходы [высота, ширина] (1-индексированный).

ŒĠLÐṂ

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

ŒĠLÐṂ – Monadic link / Full program. Takes a list of strings M as input.
ŒĠ    – Group the multidimensional indices by their values (treating M as a matrix).
  LÐṂ – And retrieve the shortest group of indices (those of the unique character).

Желе , 5 байт

ŒĠḊÐḟ

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


4

Желе , 4 байта

Возможно, это мог быть просто комментарий для мистера Xcoder, он очень похож ...

ŒĠEƇ

Монадическая ссылка, принимающая матрицу символов, которая выдает список из одного элемента, координата с 1 индексом (строка, столбец) сверху слева.
(... Как полная программа, заданная аргументом, отформатированным так, что при синтаксическом анализе получается список списков символов - то есть список строк в формате Python - печатается одна координата.)

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

Как?

ŒĠEƇ - Link: matrix, M
ŒĠ   - multi-dimensional indices grouped by Value
     -  ...due to the 2*2 minimum size and one needle this will be a list of two lists one
     -     of which will have length one (the needle coordinates as a pair) and the other
     -     containing all other coordinates as pairs
   Ƈ - filter keeping those for which this is truthy:
  E  -   all equal?
     -   ... 1 for the list of length 1, 0 for the list of at least 3 non-equal coordinates

1
Ну ... это кажется пограничным, так как умный.
Эрик Outgolfer

4

JavaScript (ES6), 55 байт

(s)(вес)sвес[Икс,Y]

s=>w=>[(i=s.indexOf(/(.)\1+(.)/.exec(s+s)[2]))%w,i/w|0]

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


JavaScript (ES6),  65  64 байта

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

[Икс,Y]

m=>m.some((r,y)=>r.some((c,x)=>!m[p=[x,y],~y&1].includes(c)))&&p

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

Как?

с(Икс,Y)р[Y]YY2×2Yзнак равно0YYзнак равно1Y


1
~y&1сохраняет байты над y&1^1.
Нейл

4

Java 8, 132 111 байт

m->{int c=m[0][0],i=0,j;for(c=m[1][0]!=c?m[1][1]:c;;i++)for(j=m[i].length;j-->0;)if(m[i][j]!=c)return i+","+j;}

-8 байт (и -13 более неявно) благодаря @dana .

Ввод как символьная матрица.

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

Объяснение:

m->{                    // Method with char-matrix parameter and String return-type
  int c=m[0][0],        //  Character to check, starting at the one at position 0,0
      i=0,j;            //  Index integers
  for(c=m[1][0]!=c?     //  If the second character does not equal the first:
         m[1][1]        //   Use the character at position 1,1 instead
        :c;             //  Else: keep the character the same
      ;i++)             //  Loop `i` from 0 indefinitely upwards:
    for(j=m[i].length;j-->0;)
                        //   Inner loop `j` in the range (amount_of_columns, 0]:
      if(m[i][j]!=c)    //    If the `i,j`'th character doesn't equal our character to check:
        return i+","+j;}//     Return `i,j` as result

1
124 - окончательное returnутверждение никогда не должно быть ударено. Может быть, есть лучший способ сохранить внешний цикл?
Дана

@ Дана Спасибо! Что касается: « Может быть, есть лучший способ сохранить внешний цикл? », Конечно, есть; просто удалив его, чтобы он превратился в бесконечный цикл. И тогда return"";он недоступен и может быть удален. : D Так что -21 байт благодаря тебе.
Кевин Круйссен

Интересно ... Я попытался удалить условие внешнего цикла и получал unreachable codeошибку. Не знал, что устранение финала returnбыло исправлением.
Дана

Что именно делает оператор -> во внутреннем цикле? Я пытался найти документы Java для этого синтаксиса, но не смог ничего найти
KBusc

1
@KBusc Это два оператора: i--и >. :) Смотрите этот так ответ для получения дополнительной информации. Таким образом, i > 0выполняется сначала, проверяя, iбольше ли это значение 0. А затем iуменьшается на 1 с i--, прежде чем оно входит в тело цикла.
Кевин Круйссен

3

MATL , 12 8 байт

tX:XM-&f

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

Использование modeфункции в качестве мажоритарного детектора. Возвращает 1 основанные индексы.

 t           % duplicate the input
  X:         % turn the copy into a linear array
    XM       % find the arithmetic mode of that (the 'haystack' character)
      -      % Subtract that from the original input
       &f    % find the position of the non-zero value in that result

-4 символа благодаря @LuisMendo


1
@ LuisMendo Спасибо. Я не думаю, что я знал о 2 выходной версии find, даже в MATLAB. (Привет, кстати!)
sundar - Восстановить Монику

3

Wolfram Language 37 58 байт

Моя более ранняя запись не правильно обрабатывает случай, когда "нечетный символ" был в верхнем левом углу матрицы. Это делает.

#~Position~Keys[TakeSmallest[Counts@Flatten@#,1]][[1]]&

Counts@Flatten@#списки , сколько каждый символ в массиве, #.

TakeSmallest[...,1] возвращает наименее частое число в форме правила ассоциации, такого как <| "Z"->1|>

Keys...[[1]]возвращает «ключ» к единственному элементу в ассоциации - наименее используемому символу. («Z» в данном случае)

#~Position~...возвращает затем положение ключа в исходной матрице #.


3

Perl 5 -p00, 52 45 байт

/^(.)(\1*
)*(\1*)|^/;$_=$&=~y/
//.$".length$3

45 байт

52 байта

Как

  • -p00: нравится, -nно и печать, режим абзаца
  • /^(.)(\1* )*(\1*)|^/ : соответствует либо
    • от начала $1: первый символ $2,: повторение (не используется) $3,: символы перед «иглой» в строке, $&все совпадение
    • или нулевая строка (позиция 0) без захвата.
  • $_= : назначить переменную ввода / аргумента по умолчанию
  • так $&=~y/ //что число новых строк$&
  • .$".: объединить с $"(пробел по умолчанию) и объединить
  • length$3 : длина $3

3

R 42 байта

function(m)which(ave(m,m,FUN=length)==1,T)

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

Вход: матрица стога сенаm

Выход: (row,col) вектор - индекс, начинающийся с1


1
Хорошая работа, и добро пожаловать в PPCG! Я считаю, что это 42 байта, так как f=может быть опущено из числа байтов, но не function(m)=.
BLT

@BLT Я не был уверен в этом, но спасибо за
заголовки



2

Python 2 , 53 47 байт

lambda s,w:divmod(s.find(min(s,key=s.count)),w)

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

Позвонить как f("########N###########", 5)(разрешено в комментарии ). Выходы(y, x) .

Эрик сохранил 6 байтов, предлагая переставить вывод + используя divmod. Благодарность!


Вы можете изменить порядок вывода, так что вы можете использовать divmodвстроенный .
Эрик Outgolfer

2

PowerShell , 107 98 82 77 байт

$l=@{}
$args|%{if($_-10){$l.$_+=$x++,+$y}else{$x=0;++$y}}
$l|% v*|? c*t -eq 2

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

Принимает забрызганную строку с LFs. Возвращает место с нулевым индексом x, y. раскатали:

$locations=@{}                      # make a hashtable. key=char, value=location array
$args|%{
    if($_-10){                      # if current char is not LF
        $locations.$_+=$x++,+$y     # add $x,$y to hashtable value and move $x to next pos
    }else{
        $x=0;++$y                   # move $x,$y to next line
    }
}
$locations|% Values|? Count -eq 2   # find and output location array with 2 elements (x,y)



1

Сетчатка 0.8.2 , 41 байт

s`(?=(.)+\1)(.*?¶)*(.*)(?!\1|¶).+
$.3,$#2

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

s`

Разрешить .совпадать с новыми строками. Это стоит 3 байта (3 байта - ?перед ), но экономит 6 байтов.

(?=(.)+\1)

Посмотрите вперед на двух одинаковых персонажей. \1затем становится сеном.

(.*?¶)*

Подсчитайте количество новых строк перед иглой.

(.*)

Захватите сено слева от иглы.

(?!\1|¶)

Убедитесь, что игла не сено или новая строка.

.+

Подходим остаток сена, чтобы результат заменил его.

$.3,$#2

Выведите ширину левого сена и количество новых строк.


1

C # (интерактивный компилятор Visual C #) , 82 байта

x=>w=>{int y=x.IndexOf(x.GroupBy(c=>c).Last(g=>g.Count()<2).Key);return(y%w,y/w);}

Спасибо Дане за то, что она сбрила 6 байтов!

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

Старое решение, 106 байт

n=>m=>{var z=n.Distinct();int d=n.IndexOf(n.Count(c=>c==z.First())>1?z.Last():z.First());return(d%m,d/m);}

Оба принимают входные данные в виде строки и целого числа, определяющего количество столбцов.

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


@dana никогда не знала, что Enumerable.Last()приняла делегата, спасибо
Embodiment of Ignorance

1

Java 8, 104 байта

(x,w)->{int i=0,p=x.length;for(;i<p;i++)if(x[i]!=x[(i+1)%p]&&x[i]!=x[(i+2)%p])break;return i/w+","+i%w;}

Входные данные - это массив char и целое число, указывающее ширину строки.

Выходные данные начинаются с нуля, вертикальные, а затем горизонтальные (т. Е. Номер строки, а затем номер столбца)

Объяснение:

(x,w)->{
    int i=0, p=x.length;
    for (;i<p;i++)          //iterate through characters in x
      if (x[i]!=x[(i+1)%p] && x[i]!=x[(i+2)%p])    //compare x[i] with the two subsequent characters in array, wrapping around if necessary
        break;
    return i/w+","+i%w;}  //return row number then column number, zero-based

1

Питон 3 , 93 89 85 58 байт

Полное переписывание взятие ввода , как concatenated string, width:

lambda g,w:divmod(g.index({g.count(c):c for c in g}[1]),w)

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


Оригинальный ответ:

def k(g):t=''.join(g);return divmod(t.index({t.count(c):c for c in t}[1]),len(g[0]))

РЕДАКТИРОВАТЬ: Сохранено 4 байта путем замены строки / отступ для точек с запятой. Сохранено еще 4 байта с помощью divmod(спасибо @JonathanFrech).

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

Я знаю, что это может быть намного короче, но я просто хотел попытаться обойти это dictпонимание.


1
Использование divmodспасло бы пять байтов.
Джонатан Фрех

0

MATL , 11 байт

tX:YmyYk-&f

Выход - строка, затем столбец; 1 на основе.

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

объяснение

t    % Implicit input. Duplicate
X:   % Linearize into a column
Ym   % Compute mean (characters are converted to ASCII codes)
y    % Duplicate from below: pushes input again
Yk   % Closest value: gives the input value that is closest to the mean
-    % Subtract, element-wise. Gives non-zero for the value farthest from the mean
&f   % Two-output find: gives row and column indices of nonzeros. Implicit display

0

Pyth, 15 14 12 байт

.Dxz-zh.-z{z

Принимает ввод как длину строки и ввод без строк и выводит как [строка, столбец].
Попробуй здесь

объяснение

.Dxz-zh.-z{z
       .-z{z    Subtract one of each character from the input.
      h         Take the first.
    -z          Remove all instances from the input.
  xz            Find the remaining character in the input.
.D          Q   Take the result divmod the (implicit) length of the row.

Старый подход

mxJmt{kdeSJ.TB

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

объяснение

mxJmt{kdeSJ.TB
           .TBQ   Take the (implicit) input and its transpose...
m      d          ... and for each...
   mt{k           ... deduplicate each row...
 xJ     eSJ       ... and find the index of the largest.     

0

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

≔§⎇⌕θ§θ¹ηθ⁰ζSθW⁼№θζLθ«⊞υωSθ»I⌕Eθ⁼ιζ⁰,ILυ

Попробуйте онлайн! Ссылка на подробную версию кода. Должно быть, я что-то делаю не так, потому что это почти столько же, сколько отвечает Retina. Объяснение:

≔§⎇⌕θ§θ¹ηθ⁰ζ

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

SθW⁼№θζLθ«⊞υωSθ»

Продолжайте читать строки, пока не найдете строку, сено которой меньше ее длины.

I⌕Eθ⁼ιζ⁰,ILυ

Выведите позицию несовпадающего элемента, а затем количество ранее прочитанных строк.


0

MATLAB, +68 22 байта

[r,c]=find(v~=v(1));if size(r,1)>1 disp([1,1]);else disp([r,c]);end;

Если бы я мог исключить какой-либо один случай, такой как [1,1]в этом решении, я мог бы сохранить несколько байтов.

Обновленное решение :

@(v)find(v-mode(v(:)))

Спасибо @sundar за помощь в решении особого случая и экономию 42 байта! Кроме того, спасибо @Luis_Mendo за предложения и сохранение мне еще 2 байта!


Я думаю, что вы можете избавиться от проверки на [1,1]случай, используя mode(v(:))вместо v(1).
sundar - Восстановить Монику

Вы должны обернуть свой код так, чтобы он был полной программой или функцией; Вы не можете предполагать, что входные данные находятся в переменной v. Кроме того , вы , вероятно , можете заменить ~=на -и удалить окончательный;
Луис Mendo

0

Рёда , 81 байт

f a{i=indexOf;l=i("
",a)+1;chars a|sort|count|[[_2,_1]]|min|i _[1],a|[_%l,_1//l]}

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

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

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