Lookalike shapes
Python, 61 bytes
lambda a,b,l:[i for i,(x,y)in enumerate(l)if x/y in[a/b,b/a]]
Yes, I'm using spending 9 chars to write enumerate
. Takes input like 1, 2, [(1, 9), (3,6), (2, 5), (16, 8)]
. For Python 2, input values need to be written as floats.
One char longer (62) in 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
CJam, 22 20 19 bytes
{:$::/_0=f=ee::*0-}
The above is an anonymous function that pops a single array of floating point pairs (first pair is needle) from the stack and pushes the array of 1-based indexes in return.
Try it online in the CJam interpreter.
How it works
:$ 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.
Haskell, 48 bytes
(a!b)l=[i|(i,(x,y))<-zip[0..]l,x/y+y/x==a/b+b/a]
Try it online!
Call this like (!) 1 2 [(1, 9), (3,6), (2, 5), (16, 8)]
.
A near-port of my Python answer. The expression zip[0..]l
enumerates the list with its indices.
The expression x/y+y/x==a/b+b/a
checks that the ratio x/y
is either a/b
or b/a
, since the function f(z) = z + 1/z
has f(z) = f(1/z)
and no other collisions.