相似形状


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 2015年

除了索引,我们还可以自己输出实际相似的形状吗?
orlp 2015年

@orlp没有!!!:D
kirbyfan64sos 2015年

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)]
凯文·克鲁伊森

Answers:



11

Python,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,需要将输入值编写为浮点数。

Python 3中再增加一个字符(62):

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/bb/a,因为该函数f(z) = z + 1/z具有f(z) = f(1/z)并且没有其他冲突。


也许让h操作员接受三个参数?那将节省一个字节,我认为它将不超出规则。
dfeuer

@dfeuer当然,现代标准绝对允许这样做,尽管回想起来,使用I / O带来的自由还很模糊。
xnor

7

雪人1.0.2,61个字符

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

纯乱码(除非您碰巧认识了Snowman),也完全符合该语言的设计目标,即尽可能地使人困惑。

输入格式同在后,输出格式也同样减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]在Snowman中,以直观的方式()进行操作会长得多:(0aa`NiN`aA|,nD并且这假设我们不必担心会与其他现有变量混淆)。相反,我使用带有“ divide”谓词的“ fold”方法,对于两个元素组成的数组,它实现了相同的目的。

  • 0AAgaA看起来足够无害,但实际上是将a存储0到变量中,然后采用索引大于该值的所有变量(因此,除第一个变量外的所有变量)。但是诀窍在于,我使用而不是AaG(它将摆脱原始数组和0AAg(同时保留两者)。现在,我使用aAat-index,使用相同的方法0来获取数组的第一个元素-此外,它处于消费模式(aA而不是aa),因此它也摆脱了0和原始数组,现在对于我们。

    0AAgaA*|las ,基本上在一个字符上完成了与GolfScript相同的操作:(。但是,按照雪人的标准,我仍然认为它非常不错。:)


3

Mathematica,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好点,会解决。
Maltysen 2015年

例如,这在包含重复元素的输入上失败,1,2并且[(1, 2), (2, 4), (1, 2)]会给出[0, 1, 0]而不是正确的[0, 1, 2]
orlp 2015年

我想接受这个,因为它最短的,但是@orlp提到的问题是否已解决?
kirbyfan64sos 15/09/14

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扩展),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

输出格式与Dyalog主要答案相同。

感谢Adám打高尔夫球+扩展的帮助。


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

谢谢。首先尝试检查是
法师

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

K5,19个字节

我认为这可以解决问题:

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

取得第一个是“ main”的对的列表。通过除以每对的排序维度来计算比率。返回匹配对的0索引位置的列表。(可以说,我选择的输入格式使此索引为-1-如果这被认为在a 1+开头无效,并在程序的大小上添加两个字符。)

用法示例:

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

这在运行 -请注意,我隐式依赖于分工总是产生浮点结果。如果在输入中为所有数字添加小数点并在后面添加空格,则在Kona中可以使用_


2

八度/ Matlab,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

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

如果那种奇怪而又特定的输入格式在作弊,那会更长一些……

Brachylog,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索引)。如果允许所有三种输出格式:索引,索引,索引等等,那将是一个更好的挑战。过滤以保留真实值;真假值列表(如您现在的列表),而不是仅允许的索引。
凯文·克鲁伊森

@KevinCruijssen“您可以选择输出的确切格式和顺序。在APL中,将索引存储为布尔向量是非常普遍的做法,但是您是对的,可能应该澄清一下。
dzaima

好吧,我读“ 你可以选择索引是否零或1为主,以及输出的准确格式和顺序。 ”,因为它可以[0,1,4][1,2,5]4\n0\n15 2 1,等等,等等,因为它仍然表示指数。但是我已经要求OP进行澄清(如果他们有回应,因为这是4年的挑战)。在我的05AB1E答案中,如果索引是必需的,则表示14字节;如果允许其他两个选项中的任何一个,则表示8字节。无论如何,我赞成你的回答。:)
Kevin Cruijssen



1

电源外壳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个字节,子句。

PowerShell61 59字节

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

在线尝试!

使用条件索引根据比率是否对齐在当前从零开始的索引和null之间切换。幸运的是,在这种情况下,$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

@ kirbyfan64sos对不起,您没有看到这一部分。它是固定的(但我确定我可以打更多的高尔夫球)
DankMemes

这些不是JSON对象,而是普通的javascript对象。JSON是一种数据传输格式。
edc65

0

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

J oins在那里,因为05AB1E不能确定指数多维名单AFAIK


如果输出正确的宽度/高度对,或基于输入列表输出正确/错误值的列表,则可能是8 个字节

ʒ‚ε{ü/}Ë

在线尝试验证所有测试用例

ε‚ε{ü/}Ë

在线尝试验证所有测试用例

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.