Benzeyen şekiller


23

Benzer rakamlar

Yanlarındaki oranlar aynıysa, iki dikdörtgen benzerdir .

Bu iki dikdörtgeni göz önünde bulundurun; 5 satır uzunluğunda ve 11 karakter genişliğinde bir dikdörtgen:

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

ve 10 çizgi uzunluğunda ve 22 karakter genişliğinde bir dikdörtgen:

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

Bu şekiller benzerdir, çünkü yanlarındaki oranlar aynıdır. İle (resmi olarak ifade etmek gerekirse h kısa tarafı olan ve w uzun kenarı olmak üzere):

h1w1=h2w2

Ayrıca şunları da yapabilirsiniz:

h1h2=w1w2

Meydan okuma

"Ana" bir dikdörtgen ve bazı "diğer" dikdörtgenler alan ve "diğerlerinin" hangisinin "ana" ile aynı olduğunu yazdıran bir program veya işlev yazın.

Girdi

Bir şekil ve şekillerin listesi. Her şekil, dikdörtgenin genişliğini ve yüksekliğini belirten sıfır olmayan 2 pozitif tam sayıdan oluşur. Örneğin, bu:

(4,2), (3,9)

iki dikdörtgen, bir 4x2 ve bir 3x9'u gösterir. Ancak girişin tam formatı istediğiniz olabilir.

Çıktı

"Diğer" in göstergeleri "ana" ile benzerdir. Endekslerin 0- veya 1-temelli olup olmadığını ve çıktının tam biçimini ve sırasını seçebilirsiniz.

Örnek program

Python'da:

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

Örnek giriş ve çıkış

Giriş:

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

Çıktı:

set([0, 1])

Giriş:

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

Çıktı:

set([2])

Kazanan

Bu kod golf, bu yüzden en kısa gönderim kazanır.

notlar

  • Bu söylemeden geçmeli, ancak standart boşluklar yasaklandı .
  • Benzer rakamları bulmak için hiçbir yerleşik kullanılamaz. (Var olup olmadığını bile bilmiyorum, ama şaşırmam!)

Kayan nokta bölmesine izin verilir mi? Kabul [1.0 2.0]edilebilir bir giriş formatı olur mu?
Dennis

@Dennis Seçtiğiniz dil garip bir şekilde kayar nokta hassasiyetine sahip olmadığı ve bu nedenle test durumlarının başarısız olması koşuluyla, iyi olması gerekir. ;)
kirbyfan64sos

Endeksler yerine gerçek benzer şekilleri kendileri de çıkarabilir miyiz?
orlp

@orlp Hayır !!! : D
kirbyfan64sos

3
Endekslerin çıktı formatı zorunlu mu? Bir test için benzeri [(1,2), (2,4), (1,9), (2,5), (16,8)], okunur [0,1,4]ve [1,2,5]izin veya olabilir biz de çıktı [1,1,0,0,1]ya [(1,2), (2,4), (16,8)]?
Kevin Cruijssen

Yanıtlar:



11

Python, 61 bayt

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

Evet, yazmak için 9 karakter harcıyorum enumerate. Gibi girdi alır 1, 2, [(1, 9), (3,6), (2, 5), (16, 8)]. Python 2 için, giriş değerlerinin float olarak yazılması gerekir.

Python 3'te bir karakter daha (62):

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

Bunu açıklar mısın? Neler olduğunu bilmek istiyorum.
The_Basset_Hound 4'15

Giriş listesindeki her öğe için @BassetHound, anlama idizin ve (x,y)nokta olarak açılır . Ardından, değerin x/yilk iki sayının quotient ( a/b) değerine veya tersine ( ) eşit olup olmadığını kontrol eder b/a. Bu değerlerden birine eşitse, bu değer ilisteye eklenir, aksi takdirde atılır.
FryAmTheEggman 4:15

9

CJam, 22 20 19 bayt

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

Yukarıdaki, yığından tek bir kayan nokta çifti dizisi (birinci çift iğnedir) açan ve buna karşılık olarak 1-bazlı indeks dizisini iten isimsiz bir fonksiyondur.

Çevrimiçi olarak deneyin CJam tercümanında .

Nasıl çalışır

:$                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 bayt

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

Çevrimiçi deneyin!

Buna şöyle diyoruz (!) 1 2 [(1, 9), (3,6), (2, 5), (16, 8)] .

Python cevabımın yakın limanı . İfadezip[0..]l , listeyi indeksleriyle numaralandırır.

İfade , işleve sahip olduğundan ve başka bir çarpışma x/y+y/x==a/b+b/aolmadığından, oranın x/yya a/bda olduğunu kontrol eder .b/af(z) = z + 1/zf(z) = f(1/z)


Belki hbir operatörü üç argüman alarak yapabilirim ? Bu bir bayt kurtaracaktı ve bence kurallar dahilinde kalacaktı.
dfeuer

@dfeuer Elbette, modern standartlara göre kesinlikle izin veriliyor, ancak geri dönüp G / Ç ile hangi özgürlüklerin alınabileceğini belirsiz hale getirdi.
Xnor

7

Kardan adam 1.0.2 , 61 karakter

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

Saf saçma (Snowman'ı tanımadığınız sürece), yani tam olarak dilin tasarım hedefiyle mümkün olduğunca kafa karıştırıcı olma doğrultusunda.

Giriş biçimi yazıdakiyle aynıdır, çıktı biçimi de aynı eksidir set(ve) .

Ungolfed (veya büyütülmemiş, gerçekten):

}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

Bu oyunda kullandığım bazı numaralardan gurur duyuyorum:

  • Yazıdakiyle aynı giriş biçimini kullandım. Ama bir şekilde ayrıştırmaya çalışmak yerine, bu gerçekten dağınık bir hale gelmek yerine, sadece iki satırı birleştirdim ve sonra tüm sayıları tek bir büyük diziye çıkarmak için bir regex kullandım (daha sonra yaptığım 2aG, yani her gruba 2).

  • :nD;aFoldukça süslü. Sadece iki elemanlı bir dizi alır ve ilkini ikincisine böler. Bu oldukça basit görünüyor, ancak bunu sezgisel bir şekilde ( a[0]/a[1]) yapmak Snowman'da çok daha uzak olurdu: 0aa`NiN`aA|,nD(ve diğer mevcut değişkenlerle uğraşma konusunda endişelenmek zorunda kalmayacağımızı varsayıyoruz). Bunun yerine, "fold" yöntemini, iki öğeden oluşan bir dizi için aynı şeyi gerçekleştiren "bölme" ifadesiyle kullandım.

  • 0AAgaAYeterince zararsız görünüyor, ama gerçekte yaptığı şey 0, değişkenlere bir a kaydetmek, ardından tüm değişkenleri bundan daha büyük bir dizine sahip (yani birincisi dışındaki tüm değişkenler) alıyor. Ama püf noktası AaG(orijinal diziden kurtulacak olan yerine) yerine, her ikisini de tutan 0kullandım AAg. Şimdi , dizinin ilk elemanını elde etmek için aynı olanı aAkullanarak, dizini kullanıyorum - üstelik bu, tüketim modunda ( bunun yerine ), yani0aAaa0 artık çöp olan orijinal diziden de bize.

    Ne yazık ki, 0AAgaA*|GolfScript bir karakter yaptığı aslında aynı şeyi yapar: (. Ancak, Snowman standartlarına göre hala oldukça iyi olduğunu düşünüyorum. :)


3

Mathematica, 41 bayt

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

Kullanımı:

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

1
Sadece Mathematica'nın bir şekilde ortaya çıkacağını biliyordum !
kirbyfan64sos

3

Pyth - 14 bayt

Bölümleri karşılaştırarak filtreler, sonra eşler indexOf.

xLQfqcFSTcFvzQ

Test Takımı .


Bu ana şekli sıralamaz, bu nedenle ana şeklin ilk yan uzunluğu daha büyük olduğunda yanlış cevap verecektir. Bkz bu test case
isaacg

@ isaacg iyi nokta, çözecektir.
Maltysen

Bu, tekrarlanan elemanlarla yapılan girişlerde başarısız olur, örneğin 1,2ve[(1, 2), (2, 4), (1, 2)] verecek [0, 1, 0]doğru yerine [0, 1, 2].
orlp

O zamandan beri, bu bir kabul etmek istiyoruz olan en kısa, ama sorun @orlp sabit sözü edilir?
kirbyfan64sos

1
@ kirbyfan64sos
kirbyfan64sos

3

APL (Dyalog Unicode) , 16 13 bayt SBCS

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

Çevrimiçi deneyin!

-3, @ngn için teşekkürler!

Açıklama:

(=.×∘⌽∨=.×)⍤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)

Çıktı formatı, 1 1 0 0 1"öteki" dikdörtgenin benzeri görünen bir ikili vektördür .

APL (Dyalog Genişletilmiş) , 11 bayt SBCS

=/-×⍥(⌈/)¨⌽

Çevrimiçi deneyin!

Açıklama:

=/-×⍥(⌈/)¨⌽  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

Çıkış formatı ana Dyalog cevabı ile aynıdır.

Adám'a golf yardımları için teşekkürler + Genişletilmiş.


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

Teşekkürler. Önce bunu incelemeye çalışacağım
Ven

2

Julia, 62 bayt

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

findFonksiyon bir Boole vektöründe doğru elemanları yerleştirir..*Vektörlerin elementwise çarpımını yapar.

Ungolfed:

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

Kullanımı:

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

2

K5, 19 bayt

Bunun hile yapacağını düşünüyorum:

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

İlki "ana" olan çiftlerin bir listesini alır. Her çiftin sıralanmış boyutlarını bölerek oranı hesaplar. Eşleşen çiftlerin 0 indeksli konumlarının bir listesini döndürür. (tartışmalı seçtiğim giriş formatı bu -1 indeksli yapar - eğer bu geçersiz1+ başlangıçta ve programımın boyutuna iki karakter ekler.)

Kullanım örneği:

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

Bu OK'de çalışır - örtük olarak her zaman kayan nokta sonuçları üreten birime bağlı olduğumu unutmayın. Girişteki tüm sayılara bir ondalık işareti eklerseniz ve sonradan bir boşluk eklerseniz Kona'da çalışır _.


2

Octave / Matlab, 44 bayt

İsimsiz bir işlev kullanma:

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

Sonuç 1 tabanlı endekslemededir.

Kullanmak için, işlevi tanımlayın

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

ve aşağıdaki biçimde arayın

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

Şunları yapabilirsiniz çevrimiçi denemek .


Sonuç mantıksal dizinlemede olabilirse ( 0benzer olmadığını 1gösterir, benzer olduğunu gösterir): 38 bayt :

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

Yukarıdaki ile aynı örnek:

>> @(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

Brachylog , 14 bayt

z{iXhpᵐ/ᵛ∧Xt}ᵘ

Çevrimiçi deneyin!

Girdiyi , ana dikdörtgeni içeren bir liste ve diğer dikdörtgenlerin listesini içeren bir liste olarak alır (test durumu 1'dir [[[1,2]],[[1,2],[2,4]]]) ve çıktı değişkeni üzerinden 0 tabanlı dizinlerin bir listesini çıkarır.

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.

Bu tür garip ve belirli giriş biçimlendirme hile yapıyorsa, biraz daha uzun ...

Brachylog , 18 bayt

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

Çevrimiçi deneyin!

Girdiyi ana dikdörtgeni ve diğer dikdörtgenlerin listesini içeren bir liste olarak alır (test durumu 1 daha belirgindir [[1,2],[[1,2],[2,4]]]) ve çıktı değişkeni üzerinden 0 tabanlı dizinlerin bir listesini çıkarır.

{               }ᵘ    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.

İki genişlik-yükseklik çiftinin benzer dikdörtgenleri temsil edip etmediğini belirlemek için, sadece dört byte pᵐ/ᵛ(paylaşılan oranı veya bunun karşılığını veren) alır. Geri kalan her şey karşılaştırmak için birden fazla dikdörtgeni ele alıyor ve çıktı endeksli.


2

dzaima / APL , 7 bayt

=/⍤÷⍥>¨

Çevrimiçi deneyin!

Bir boolean vektörü yerine bir indisler listesi çıkaran 8 bayt

      ¨ 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

Güzel bir cevap olmasına rağmen, endeksleri çıkarmamız gerekiyor. Bu nedenle, TIO test durumunuz ya sonuçlandı ya [0,1,4]da [1,2,5](dilinizin 0- veya 1 indeksli olup olmadığından emin değil). Üç çıktı formatına da izin verilirse imho daha iyi bir zorluk olurdu: endeksler; truthy değerlerini tutmak için filtre; Sadece izin verilen indeksler yerine, truthy / falsey değerlerinin listesi (şimdiki gibi).
Kevin Cruijssen

@KevinCruijssen "Çıktının tam biçimini ve sırasını [...] seçebilirsiniz." APL'de endeksleri bir boolean vektörü olarak saklamak çok yaygın bir uygulamadır, ancak haklısınız, muhtemelen açıklığa kavuşturulması gerekir.
dzaima

Eh, okuma " Sen endeksleri 0- veya olup olmadığını seçebilir yanı çıkışın tam format ve sipariş olarak, 1 tabanlı. Olabildiğinin" [0,1,4], [1,2,5], 4\n0\n1, 5 2 1, vs vs, hala açıklamalarından bu yana indeksleri . Fakat OP'den netleşmesini istedim (cevap verirse, 4 yıllık bir mücadele olduğundan). Benim 05AB1E cevabımda, diğer iki seçeneğin herhangi birine izin veriliyorsa, endekslerin zorunlu olması durumunda 8 byte'a karşılık 14 bayt anlamına gelir. Ne olursa olsun, cevabınızı yükselttim. :)
Kevin Cruijssen



1

PowerShell , 58 56 bayt

Mazzy x2 sayesinde -2 bayt

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

Çevrimiçi deneyin!

Bu biraz suistimal input may be however you desire , ilk şeklin bileşenlerinin 3 bayttan tasarruf etmek için ayrı ayrı gelmesini sağlayarak yan tümce kullanır.

PowerShell , 61 59 bayt

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

Çevrimiçi deneyin!

Geçerli sıfıra dayalı endeks ile oranların aynı hizada olmasına bakılmaksızın null arasında geçiş yapmak için koşullu indekslemeyi kullanır. Neyse ki, bu durumda, $iyazdırılıp yazdırılmadığına bakılmaksızın artış.


1
Bunun -yerine kullanırsanız daha fazla tasarruf edebilirsiniz -ne.
mazzy

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

Alternatif, ayrıca 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)

Giriş, bir JSON nesnesi ve bir JSON nesnesi dizisi olarak alınır.

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

Bunun ikinci test durumuyla işe yaradığını sanmıyorum.
kirbyfan64sos

@ kirbyfan64sos üzgünüm o kısmı görmedim.
Düzeldi

Bunlar JSON nesneleri değil, bunlar düz javascript nesneleridir. JSON bir veri aktarım formatıdır.
edc65

0

05AB1E , 15 14 bayt

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

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

Açıklama:

ʒ               # 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)

JÇok boyutlu listeleri afaik üzerinde 05AB1E indeksleri tespit edemez, çünkü oins vardır


Doğruluktaki genişlik / yükseklik çiftlerinin çıktısını almak ya da girdi listesine dayalı bir öteleme / falsey değerleri listesini çıkarıyorsanız, bunun yerine 8 bayt olabilir :

ʒ‚ε{ü/}Ë

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

ε‚ε{ü/}Ë

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.