Lookalike форми


23

Подібні цифри

Два прямокутника схожі, якщо співвідношення їх сторін однакові.

Розглянемо ці два прямокутники; прямокутник у 5 ліній у висоту та 11 символів у ширину:

===========
===========
===========
===========
===========

і прямокутник у 10 ліній заввишки та 22 символи в ширину:

======================
======================
======================
======================
======================
======================
======================
======================
======================
======================

Ці форми схожі, оскільки співвідношення їх сторін однакові. Формально сказати (при цьому h є найкоротшою стороною, а w - найдовшою стороною):

h1w1=h2w2

Ви також можете зробити:

h1h2=w1w2

Змагання

Напишіть програму або функцію, яка займає "головний" прямокутник і деякі "інші" прямокутники та друкує, які з "інших" схожі на "основні".

Вхід

Форма та перелік фігур. Кожна форма складається з 2 ненульових натуральних чисел, які позначають ширину і висоту прямокутника. Наприклад, це:

(4,2), (3,9)

позначає два прямокутники, 4x2 та 3x9. Точний формат вводу, можливо, не бажає.

Вихід

Показники "інших" фігур, схожі на "основні". Ви можете вибрати, чи базуються показники на 0 або 1, а також точний формат і порядок виводу.

Зразок програми

На Python:

main = eval(raw_input()) # The main rectangle.
rects = eval(raw_input()) # The list of rectangles.
similar = set()
for i, rect in enumerate(rects):
    if max(main)*min(rect) == min(main)*max(rect): # Cross-multiply
        # They are similar.
        similar.add(i)

print similar

Зразок введення та виведення

Вхід:

(1, 2)
[(1, 2), (2, 4)]

Вихід:

set([0, 1])

Вхід:

(1, 2)
[(1, 9), (2, 5), (16, 8)]

Вихід:

set([2])

Перемога

Це код-гольф, тому виграє найкоротше подання.

Примітки

  • Це само собою зрозуміло, але стандартні лазівки заборонені .
  • Ніяких вбудованих приміщень для розміщення подібних фігур не можна використовувати. (Я навіть не знаю, чи це існує, але я не здивуюсь!)

Чи дозволено використання поділу з плаваючою комою? Чи [1.0 2.0]прийнятний формат введення?
Денніс

@Dennis Якщо вибрана мова не має дивно низької точності з плаваючою точкою, і тому тестові випадки не вдається, це повинно бути добре. ;)
kirbyfan64sos

Ми можемо замість індексів виводити самі подібні фігури?
orlp

@orlp Nope !!! : D
kirbyfan64sos

3
Чи обов'язковий формат виведення індексів? Для тестового випадку, як [(1,2), (2,4), (1,9), (2,5), (16,8)], дозволено лише [0,1,4]та [1,2,5]дозволено, чи ми можемо також вивести [1,1,0,0,1]чи [(1,2), (2,4), (16,8)]?
Кевін Круїссен

Відповіді:



11

Пітон, 61 байт

lambda a,b,l:[i for i,(x,y)in enumerate(l)if x/y in[a/b,b/a]]

Так, я використовую 9 символів, щоб писати enumerate. Приймає вхід як 1, 2, [(1, 9), (3,6), (2, 5), (16, 8)]. Для Python 2 вхідні значення потрібно записувати як плавні.

На один знак довше (62) на Python 3:

def f(a,b,l,i=0):
 for x,y in l:b/a!=x/y!=a/b or print(i);i+=1

Ви не проти пояснити це? Я хотів би знати, що відбувається.
The_Basset_Hound

@BassetHound для кожного елемента списку введення розуміння розпаковується iяк індекс, так і (x,y)як точка. Потім він перевіряє, чи є значення x/yрівним початковим коефіцієнтом двох чисел ( a/b) або його зворотним ( b/a). Якщо воно дорівнює одному з цих значень, це значення iдодається до списку, інакше воно відкидається.
FryAmTheEggman

9

CJam, 22 20 19 байт

{:$::/_0=f=ee::*0-}

Вищенаведене - це анонімна функція, яка вискакує один масив пар з плаваючою точкою (перша пара - голка) зі стека та виштовхує масив 1-базисних індексів натомість.

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Як це працює

:$                e# Sort each pair.
  ::/             e# [a b] -> a/b
     _0=          e# Push a copy of the array and extract the first float (needle).
        f=        e# Check which floats are equal to the needle.
          ee      e# Enumerate the resulting Booleans.
            ::*   e# Multiply each Boolean by its index.
                  e# This yields 0 for the needle (index 0) and for non-matching
                  e# haystack pairs (Boolean 0).
               0- e# Remove all zeroes from the array.

8

Haskell , 48 байт

(a!b)l=[i|(i,(x,y))<-zip[0..]l,x/y+y/x==a/b+b/a]

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

Назвіть так (!) 1 2 [(1, 9), (3,6), (2, 5), (16, 8)].

Близький порт моєї відповіді Python . Вираз zip[0..]lперераховує список з його індексами.

Вираз x/y+y/x==a/b+b/aперевіряє, чи є співвідношення x/yабо a/bабо b/a, оскільки функція не f(z) = z + 1/zмає f(z) = f(1/z)та інших зіткнень.


Можливо, змусити hоператора взяти три аргументи? Це дозволить зберегти один байт, і я думаю, що це буде дотримуватися правил.
dfeuer

@dfeuer Звичайно, це, безумовно, дозволено сучасними стандартами, хоча назад було нечіткіше, які свободи можна взяти за допомогою вводу / виводу.
xnor

7

Сніговик 1.0.2 , 61 символ

}vgvgaC"[0-9]+"sM:10sB;aM2aG:AsO:nD;aF;aM0AAgaA*|:#eQ;AsItSsP

Чистий хитрість (якщо ви не знаєте Сніговика), він точно відповідає меті дизайну мови бути максимально заплутаним.

Формат введення такий самий, як і у публікації, формат виводу також такий самий мінус set(і ).

Невольф (або насправді без змін):

}vgvgaC     // read two lines of input, concatenate
"[0-9]+"sM  // use a regex to grab all numbers
:10sB;aM    // essentially map(parseInt)
2aG         // take groups of 2 (i.e. all the ordered pairs)

// now map over each ordered pair...
:
  AsO       // sort
  :nD;aF    // fold with division - with 2 array elements, this is just a[0]/a[1]
;aM

// we now have an array of short side to long side ratios
// take out the first one
0AAgaA      // active vars beg, b=array[0], g=the rest
*|          // store first ordered pair in permavar, bring the rest to top

// select indices where...
:
  #         // retrieve first ordered pair
  eQ        // equal?
;AsI

tSsP  // to-string and output

Я дуже пишаюся деякими хитрощами, якими я користувався в цьому:

  • Я використовував той же формат введення, що і в дописі. Але замість того, щоб намагатись якось проаналізувати це, що вийшло б справді безладним, я просто з'єднав два рядки, а потім застосував регулярний вираз, щоб витягнути всі числа в один великий масив (з чим я тоді це зробив 2aG, тобто отримаю кожну групу по 2).

  • :nD;aFдосить фантазії. Він просто бере масив з двох елементів і ділить перший на другий. Що здається досить простим, але зробити це інтуїтивно зрозумілим способом ( a[0]/a[1]) було б далеко, набагато довше у Сніговика: 0aa`NiN`aA|,nD(і це припускає, що нам не потрібно турбуватися про возитися з іншими існуючими змінними). Натомість я використав метод "складання" з присудком "розділити", який для масиву з двох елементів досягає того ж самого.

  • 0AAgaAвиглядає досить нешкідливим, але те, що він насправді робить, - це збереження 0змінних, а потім приймає всі змінні з індексом, більшим за цей (так, усі змінні, крім першої). Але хитрість полягає в тому, що замість AaG(який би позбувся початкового масиву та 0), я використав AAg, який зберігає і те, і інше. Тепер я використовую aA, at-index, використовуючи той самий,0 щоб отримати перший елемент масиву - крім того, це в режимі споживання ( aAзамість aa), тож він позбавляється 0і оригінального масиву, який зараз є сміттям для нас.

    На жаль, 0AAgaA*|робить по суті те ж саме , що робить GolfScript в один символ: (. Однак я все ще думаю, що це досить приємно, за мірками Сніговика. :)


3

Математика, 41 байт

Position[a=Sort@#;Sort@#/a&/@#2,{x_,x_}]&

Використання:

Position[a = Sort@#; Sort@#/a & /@ #2, {x_, x_}] &[{1, 2}, {{1, 2}, {2, 5}, {16, 8}}]
(* {{1}, {3}} *)

1
Я просто знав, що Mathematica збирається якось придумати!
kirbyfan64sos

3

Pyth - 14 байт

Фільтрує, порівнюючи коефіцієнти, потім карти indexOf.

xLQfqcFSTcFvzQ

Тестовий сюїт .


Це не сортує основну форму, тому вона дасть неправильну відповідь, коли довжина першої сторони основної форми більша. Дивіться цей тестовий випадок
isaacg

@isaacg хороший момент, виправимо.
Мальтісен

Це не вдасться, наприклад, на входах з повторюваними елементами, 1,2і [(1, 2), (2, 4), (1, 2)]дасть, [0, 1, 0]а не правильно [0, 1, 2].
orlp

Я хочу прийняти це одне, так як він є найкоротшим, але проблема @orlp згадувалося виправлена?
kirbyfan64sos

1
@ kirbyfan64sos
orlp

3

APL (Dyalog Unicode) , 16 13 байт SBCS

(=.×∘⌽∨=.×)⍤1

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

-3 завдяки @ngn!

Пояснення:

(=.×∘⌽∨=.×)⍤1
(        )    "OR" together...
 =.    =.      ...fold by equality of:
   ×∘⌽         - the arguments multiplied by itself reversed
         x     - the argument multiplied by itself
           1  Applied at rank 1 (traverses)

Формат виводу - це двійковий вектор, подібний 1 1 0 0 1до якого "інший" прямокутник є схожим.

APL (Dyalog Extended) , 11 байт SBCS

=/-×⍥(⌈/)¨⌽

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

Пояснення:

=/-×⍥(⌈/)¨⌽  takes only a right argument: ⍵, shape: (main (other...))
            two transformations:
  -          - left (L) vectorized negation: -⍵
            - right (R): reverse. (main other) => (other main)
     (⌈/)¨   transformation: calculate the max (since L is negated, it calculates the min)
             (/ reduces over  max)
             this vectorizes, so the "main" side (with only one rect) will get repeated once for each "other" rect on both sides
   ×⍥        over multiplication: apply the transformation to both sides. F(LF(R)
=/           reduce the 2-element matrix (the "main" that's now the side of the "other") to check which are equal

Формат виводу такий самий, як і головна відповідь Діялога.

Дякуємо Adám за допомогу в гольфі + Extended.


(=.×∘⌽∨=.×)⍤1
ngn

Спасибі. Постараюся , щоб перевірити , що перший
Ven

2

Джулія, 62 байти

f(m,o)=find([(t=sort(m).*sort(i,rev=true);t[1]==t[2])for i=o])

findФункція знаходить справжні елементи булева вектора. .*виконує елементне множення векторів.

Безголівки:

function f(m::Array, o::Array)
    find([(t = sort(m) .* sort(i, rev=true); t[1] == t[2]) for i in o])
end

Використання:

f([1,2], {[1,9], [2,5], [16,8]})

2

К5, 19 байт

Я думаю, що це зробить трюк:

&(*t)=1_t:{%/x@>x}'

Бере список пар, де перша - "головна". Обчислює відношення шляхом ділення відсортованих розмірів кожної пари. Повертає список 0-індексованих позицій відповідних пар. (Можливо , вхідний формат я вибрав робить це -1 indexed- , якщо це вважається недійсною липкостью на 1+початку і додайте два символу до розміру моєї програми.)

Приклад використання:

  &(*t)=1_t:{%/x@>x}'(1 2;1 2;2 4;2 5;16 8)
0 1 3

Це працює в oK - зауважте, що я неявно залежу від поділу, що завжди дає результати з плаваючою комою. Це буде працювати в Kona, якби ви додали десяткову точку до всіх чисел у введеному коді та додали пробіл після _.


2

Октава / Матлаб, 44 байти

Використання анонімної функції:

@(x,y)find((max(x))*min(y')==min(x)*max(y'))

Результат - в 1-й індексації.

Для його використання визначте функцію

>> @(x,y)find((max(x))*min(y')==min(x)*max(y'));

і зателефонуйте в наступний формат

>> ans([1 2], [1 9; 2 5; 16 8])
ans =
     3

Ви можете спробувати в Інтернеті .


Якщо результат може бути в логічному індексуванні ( 0вказує не схоже, 1вказує подібне): 38 байт :

@(x,y)(max(x))*min(y')==min(x)*max(y')

Той самий приклад, як і вище:

>> @(x,y)(max(x))*min(y')==min(x)*max(y')
ans = 
    @(x,y)(max(x))*min(y')==min(x)*max(y')

>> ans([1 2], [1 9; 2 5; 16 8])
ans =
 0     0     1

2

Брахілог , 14 байт

z{iXhpᵐ/ᵛ∧Xt}ᵘ

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

Приймає введення як список, що містить перелік, що містить основний прямокутник і список інших прямокутників (таким є тестовий випадок 1 [[[1,2]],[[1,2],[2,4]]]), і виводить список індексів на основі 0 через вихідну змінну.

z                 Zip the elements of the input, pairing every "other" rectangle with the main rectangle.
 {          }ᵘ    Find (and output) every unique possible output from the following:
  iX              X is an element of the zip paired with its index in the zip.
    h             That element
      ᵐ           with both of its elements
     p            permuted
        ᵛ         produces the same output for both elements
       /          when the first element of each is divided by the second.
         ∧Xt      Output the index.

Якщо такий незвичайний та специфічний формат введення обман, це трохи довше ...

Брахілог , 18 байт

{hpX&tiYh;X/ᵛ∧Yt}ᶠ

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

Приймає введення як список, що містить основний прямокутник і список інших прямокутників (тому тестовий випадок 1 є більш очевидним [[1,2],[[1,2],[2,4]]]) і виводить список індексів на основі 0 через вихідну змінну.

{               }ᵘ    Find (and output) every possible output from the following:
  p                   A permutation of
 h                    the first element of the input
   X                  is X,
    &                 and
      i               a pair [element, index] from
     t                the last element of the input
       Y              is Y,
        h             the first element of which
            ᵛ         produces the same output from
           /          division
         ;            as
          X           X.
             ∧Yt      Output the index.

Щоб визначити, чи дві пари ширини-висоти представляють подібні прямокутники, просто знадобиться чотири байти pᵐ/ᵛ(які виводять коефіцієнт спільного використання або його взаємний). Все решта - це обробка декількох прямокутників для порівняння, а вихідний - індекси.


2

dzaima / APL , 7 байт

=/⍤÷⍥>¨

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

8 байт виводить список індексів замість булевого вектора

      ¨ for each (pairing the left input with each of the right)
    ⍥>    do the below over sorting the arguments
=/          equals reduce
           after
   ÷        vectorized division of the two

Хоча це гарна відповідь, ми повинні виводити індекси. Тож ваш тестовий випадок TIO повинен спричинити [0,1,4]або [1,2,5]( або не впевнений, чи ваша мова є 0- або 1-індексованою). Було б кращим завданням, якщо дозволити всі три формати випуску: індекси; фільтр для збереження правдоподібних значень; список значень truthy / falsey (як зараз), а не лише дозволені індекси.
Кевін Круїссен

@KevinCruijssen "Ви можете вибрати [...] точний формат і порядок виводу." в APL дуже поширена практика зберігання індексів як булевого вектора, але ви праві, що, мабуть, слід уточнити.
dzaima

Ну, я прочитав « Ви можете вибрати , буде чи індекси 0- або 1 на основі, а також точний формат і порядок виведення. » , Як це може бути [0,1,4], [1,2,5], 4\n0\n1, 5 2 1і т.д. і т.п., так як він по- , як і раніше вказано індекси . Але я попросив ОП уточнити (якщо вони відповідатимуть, оскільки це 4-річний виклик). У моїй відповіді 05AB1E це означатиме 14 байт, якщо індекси обов'язкові проти 8 байтів, якщо дозволений будь-який з двох інших варіантів. Незважаючи на те, я підтримав вашу відповідь. :)
Кевін Круїссен



1

PowerShell , 58 56 байт

-2 байти завдяки mazzy x2

param($x,$y,$b)$b|%{($i++)[$x/$y-($z=$_|sort)[0]/$z[1]]}

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

Це трохи зловживає input may be however you desireпунктом, оскільки компоненти першої форми надходять окремо, щоб зберегти 3 байти.

PowerShell , 61 59 байт

param($a,$b)$b|%{($i++)[$a[0]/$a[1]-($x=$_|sort)[0]/$x[1]]}

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

Використовується умовна індексація для заміни між поточним індексом, що базується на нулі, і нульовим, залежно від того, співвідносяться чи ні співвідношення. На щастя, у цьому випадку $iзбільшується, незалежно від того, надруковано чи ні.


1
Ви можете зекономити більше, якщо скористаєтесь -натомість -ne.
маззи

0

Javascript (ES6), 75

(a,b)=>b.filter(e=>e.l*a.h==a.l*e.h||e.l*a.l==a.h*e.h).map(e=>b.indexOf(e))

Альтернативно, також 75

(a,b)=>b.map((e,i)=>e.l*a.h==a.l*e.h||e.l*a.l==a.h*e.h?i:-1).filter(e=>e+1)

Введення приймається як об'єкт JSON, а масив JSON об'єктів

{
    l: length of rectangle,
    h: height of rectangle
}

Я не думаю, що це працює з другим тестом.
kirbyfan64sos

@ kirbyfan64сос вибачення не побачив цю частину. Це виправлено (але я впевнений, що можу
пограти в

Це не об'єкти JSON, це звичайні об’єкти javascript. JSON - формат передачі даних.
edc65

0

05AB1E , 15 14 байт

ʒ‚ε{ü/}Ë}J¹Jsk

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

ʒ               # Filter the (implicit) input-list by:
               #  Pair the current width/height with the (implicit) input width/height
  ε             #  Map both width/height pairs to:
   {            #   Sort from lowest to highest
    ü/          #   Pair-wise divide them from each other
              #  After the map: check if both values in the mapped list are equals
        }J      # After the filter: join all remaining pairs together to a string
          ¹J    # Also join all pairs of the first input together to a string
            s   # Swap to get the filtered result again
             k  # And get it's indices in the complete input-list
                # (which is output implicitly)

The J OINS там , тому що 05AB1E не може визначити індекси на багатовимірні списки AFAIK


Якщо виводити параметри ширини / висоти, які є truthy, або виводити список значень truthy / falsey на основі списку вхідних даних, натомість це може бути 8 байт :

ʒ‚ε{ü/}Ë

Спробуйте в Інтернеті або перевірте всі тестові випадки .

ε‚ε{ü/}Ë

Спробуйте в Інтернеті або перевірте всі тестові випадки .

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