Знайдіть голку в копиці сіна


38

Враховуючи прямокутну копицю сіна розміром принаймні 2х2, що складається з усіх однакових символів для друку 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 відповідає на запитання "Чи голка в цьому стовпчику?"), Помножуємо їх по елементах на послідовність 0,1,2 ,. .. ( True = 1і False = 0) і підсумовуйте список, тому результатом усього блоку є 0 на основі номера стовпця, де була знайдена голка.

Кращий підхід Нелленгофа, 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

@JoKing, дякую!
Рамілли

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];}

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

Безголівки:

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 (), це геніально. Дякую! Параметри функціоналу траплялися і у мене, я просто не хотів запускати потоки вхідних запитів. Я уточню з / п.
640 Кб

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

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
Це добре, адже він не тільки базується на вашому рішенні, але також я зазвичай не використовую нуд. До того ж, якось неминуче рішення може бути дуже схожим, враховуючи, що всі рішення є загальнодоступними, і це відносно легке завдання
лише для 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
Ну ... це здається прикордонним, оскільки розумний.
Ерік Аутгольфер

4

JavaScript (ES6), 55 байт

Вводиться як " (с)(ш), де с є рядок і ш- ширина матриці. Повертається[х,у].

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

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


JavaScript (ES6),  65  64 байт

Збережено 1 байт завдяки @Neil

Вводиться як матриця символів. Повертається[х,у].

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

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

Як?

Шукаємо першого персонажа c розташований за адресою (х,у) який не з’являється ніде в іншому ряду r[Y]. Ми можемо виконати цей тест на будь-якому ряду, докиYу. Тому що вхідна матриця гарантується як мінімум2×2, ми можемо просто використовувати Y=0 якщо у непарно або Y=1 якщо у рівномірний.


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твердження ніколи не повинно потрапляти. Можливо, є кращий спосіб зберегти зовнішню петлю?
дата

@dana Дякую! Що стосується: " Можливо, буде кращий спосіб продовжити зовнішню петлю? ", Безумовно, є; просто знявши його, щоб він став нескінченним циклом. І тоді 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. (Привіт, btw!)
sundar - Відновіть Моніку

3

Мова Вольфрама 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,: символи перед «голкою» у рядку, $&ціле збіг
    • або null string (позиція 0) немає захоплення.
  • $_= : призначити змінну вводу / аргументу за замовчуванням
  • тому $&=~y/ //кількість нових рядків$&
  • .$".: concatenate з $"(символом пробілу за замовчуванням) та concatenate
  • 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 Я не був у цьому впевнений, але дякую за голову :)
niko



2

Python 2 , 53 47 байт

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

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

Call as f("########N###########", 5) (allowed in a comment). Outputs (y, x).

Ерік врятував 6 байт, запропонувавши переставити вихід + за допомогою divmod. Спасибі!


Ви можете змінити порядок виводу, щоб ви могли використовувати divmodвбудований .
Ерік Аутгольфер

2

PowerShell , 107 98 82 77 байт

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

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

Бере заплетену рядок з НЧ. Повертає нульове індексування місця 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

Retina 0.8.2, 41 bytes

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

Try it online! 0-indexed. Explanation:

s`

Allow . to match newlines. This costs 3 bytes (3rd byte is the ? before the ) but saves 6 bytes.

(?=(.)+\1)

Look ahead for two identical characters. \1 then becomes the hay.

(.*?¶)*

Count the number of newlines before the needle.

(.*)

Capture the hay to the left of the needle.

(?!\1|¶)

Ensure that the needle isn't hay or a newline.

.+

Match the rest of the hay so that the result replaces it.

$.3,$#2

Output the width of the left hay and the number of newlines.


1

C# (Visual C# Interactive Compiler), 82 bytes

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

Thanks to dana for shaving off 6 bytes!

Try it online!

Old solution, 106 bytes

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);}

Both take input as a string and an integer specifying the amount of columns.

Try it online!


@dana never knew that Enumerable.Last() accepted a delegate, thanks
Embodiment of Ignorance

1

Java 8, 104 Bytes

(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;}

Input is array of char, and integer indicating row width.

Output is zero-based, vertical then horizontal (i.e., row number then column number)

Explanation:

(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

Python 3, 93 89 85 58 bytes

Complete rewrite taking input as concatenated string, width:

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

Try it online!


Original answer:

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

EDIT: Saved 4 bytes by swapping linebreak/indent for semicolons. Saved another 4 bytes by using divmod(thanks @JonathanFrech).

Try it online!

I know this could be a lot shorter, but I just wanted to try an approach around this dict comprehension.


1
Using divmod would save five bytes.
Jonathan Frech

0

MATL, 11 bytes

tX:YmyYk-&f

Output is row, then column; 1-based.

Try it online!

Explanation

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 bytes

.Dxz-zh.-z{z

Takes input as the length of the row and the input without lines and outputs as [row, column].
Try it here

Explanation

.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.

Old approach

mxJmt{kdeSJ.TB

Try it here

Explanation

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

Charcoal, 40 bytes

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

Try it online! Link is to verbose version of code. I must be doing something wrong because this is almost as long as the Retina answer. Explanation:

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

Check whether the second character in the first string is also the first character, and take the first character of the first string if so otherwise the first character of the second string if not. This is then the hay.

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

Keep reading strings until a string whose hay is less than its length is found.

I⌕Eθ⁼ιζ⁰,ILυ

Output the position of the mismatching element and then the number of strings previously read.


0

MATLAB, 68 22 bytes

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

If I could exclude any one case, such as [1,1] in this solution, I could have saved several bytes.

Updated solution:

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

Thanks to @sundar for helping me with the special case problem and saving 42 bytes! Also, thanks to @Luis_Mendo for the suggestions and saving me another 2 bytes!


I think you can get rid of the check for [1,1] case by using mode(v(:)) instead of v(1).
sundar - Reinstate Monica

You need to wrap your code so that it is a full program or a function; you cannot assume that the input is in a variable v. Also, you can probably replace ~= by -, and remove the final ;
Luis Mendo

0

Röda, 81 bytes

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

Try it online!

Takes input as a string containing newline-terminated lines. Returns a stream containing 0-indexed horizontal and vertical indexes.

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