| Bytes | Lang | Time | Link |
|---|---|---|---|
| 016 | Japt v1.4.5 | 250127T101035Z | Shaggy |
| 093 | JavaScript V8 | 250127T112526Z | Arnauld |
| 097 | Python 3 | 250128T003039Z | Lucenapo |
| 012 | Jelly | 250127T180623Z | Jonathan |
| 030 | Haskell + hgl | 250127T161738Z | Wheat Wi |
| 121 | Maple | 250127T162225Z | dharr |
| 014 | Vyxal | 250127T114805Z | lyxal |
| 038 | Charcoal | 250127T123111Z | Neil |
| 082 | Retina | 250127T105636Z | Neil |
Japt v1.4.5, 18 17 16 bytes
Takes input as a 2D array of ["element","colour"] pairs, outputs a 3D array. Any set of values can be substituted for the elements & colours.
à3 f@#søXyâ mʬ
à3 f@#\u0085søXyâ mʬ :Implicit input of 2D array
à3 :Combinations of length 3
f :Filter by
@ :Passing each X through the following function
#\u0085 : Compressed integer 133
s : To string
ø : Contains
Xy : Transpose X
â : Deduplicate each sub-array
m : Map
Ê : Length
¬ : Join
JavaScript (V8), 93 bytes
Expects a list of 9-bit integers, using a combination of the following bit-masks:
0x1, 0x2, 0x4for Fire, Water, Snow0x008, 0x010, 0x020, 0x040, 0x080, 0x100for Yellow, Orange, Red, Blue, Green, Purple
Prints triplets of integers in the same format.
f=([c,...a],m,o=[])=>c?f(a,m|c,[...o,c])|f(a,m,o):150>>m%8&!o[3]&&(m/=8,m&=m-1)&m-1&&print(o)
Try it online! (prettified I/O)
Try it online! (raw I/O)
Commented
f = ( // f is a recursive function taking:
[c, // c = next card
...a], // a[] = remaining cards
m, // m = bit-mask, initially undefined
o = [] // o[] = output
) => //
c ? // if c is defined:
f( // first recursive call where the card is selected:
a, // pass a[]
m | c, // update m with a bitwise OR with c
[...o, c] // append c to o[]
) | // end of recursive call
f(a, m, o) // second recursive call with everything unchanged
// (i.e. the card is ignored)
: // else, make sure that:
150 >> m % 8 // 1) m % 8 is in [1, 2, 4, 7]
// (either a single element bit or the 3 of them)
// by testing the bit-mask 0b10010110 = 150
& !o[3] // 2) o[3] is not defined (no more than 3 cards)
&& ( // 3) three color bits are set in m:
m /= 8, // - discard the element bits
m &= m - 1 // - remove the least significant 1
) & m - 1 // - remove the least significant 1 again
&& print(o) // print o if all conditions are met
Python 3, 97 bytes
lambda t:[(x,y,z)for x in t for y in t for z in t if-128|x^y^z==-128|x+y+z<2>(x*y*z>>33)%7<x<y<z]
Uses the following bit masks:
1,2,4,8,16,32 for colours
2048,4096,8192 for elements
Jelly, 12 bytes
œc3=ⱮḄ§BȦʋ$Ƈ
A monadic Link that accepts a list of cards as pairs of [Element, Colour] where Element and Colour are integers or characters and yields the valid sets as a list of triples of cards.
Try it online! Or see the test-suite.
How?
œc3=ⱮḄ§BȦʋ$Ƈ - Link: list of pairs of ints/chars, Cards
œc3 - combinations of three {Cards} -> Triples
Ƈ - keep those Triples for which:
$ - last two links as a monad - f(Triple):
Ɱ - map across {RightCard in Triple) with:
= - {Triple} equals {RightCard} (vectorises)
ʋ - last four links as a dyad - f(Comparisons=that, Triple):
Ḅ - convert {Comparisons} from binary
§ - sum each {of those}
B - convert {that} to binary (vectorises)
Ȧ - any & all of {that}? (here, contains no zeros when flattened?)
Note: the right argument of ʋ is not used, this was only made dyadic (i.e. is not Ʋ) because it allows the first link in the filter's chain - the dyadic =Ɱ - to not need to specify that it should use its left argument on both sides (i.e. otherwise we need to use `).
In general, a triple is being assessed as follows
Triple to check:
((Element=A, Colour=a), (Element=B, Colour=b), (Element=C, Colour=c))
=Ɱ -> Comparisons:
[[[A==A, a==a], [A==B, a==b], [A==C, a==c]],
[[B==A, b==a], [B==B, b==b], [B==C, b==c]],
[[C==A, c==a], [C==B, c==b], [C==C, c==c]],
]
Ḅ -> convert that from binary:
[[2*(A==A)+(a==a), 2*(A==B)+(a==b), 2*(A==C)+(a==c)],
[2*(B==A)+(b==a), 2*(B==B)+(b==b), 2*(B==C)+(b==c)],
[2*(C==A)+(c==a), 2*(C==B)+(c==b), 2*(C==C)+(c==c)],
]
§ -> sum each of those:
[2*(A==A)+(a==a)+2*(A==B)+(a==b)+2*(A==C)+(a==c),
2*(B==A)+(b==a)+2*(B==B)+(b==b)+2*(B==C)+(b==c),
2*(C==A)+(c==a)+2*(C==B)+(c==b)+2*(C==C)+(c==c),
]
...which is equal to:
[3 + 2 * ((A==B) + (A==C)) + (a==b) + (a==c),
3 + 2 * ((B==A) + (B==C)) + (b==a) + (b==c),
3 + 2 * ((C==A) + (C==B)) + (c==a) + (c==b),
]
Then it checks whether all three of these numbers are either three or seven by checking they are all one less than a power of two (all ones in binary).
This works because the Colours (abc) need to all be different in order not to change any number's two least significant bits (from the 3 + ), meanwhile, the Elements (ABC) need to either (a) all be different (to keep every number down to three) OR (b) all be the same (making all numbers equal seven). Note that the maximum a number can ever be is nine (when the three cards are all the same). Furthermore, no mix of threes and sevens is possible (if one expression evaluates to seven, each of the others have one of its Element equality terms so they both increase from three).
Haskell + hgl, 30 bytes
fl(mp<%(uq=:(uq*|*lq))<uz)<ss3
Takes input as a list of tuples. The interiors of the tuples can be any types with an Eq instance, I use numbers in the test case.
Explanation
Pretty straightforward. ss3 gets us all the triplets, then we use a filter (fl) to get the ones matching. The internals of the check is the most interesting part.
uzunzips the list of tuples into a tuple of lists.=:"parallelizes" the two operations we want to do. This just applies each of them separately to the arguments of a tuple.uqchecks the input is uniqueuq*|*lqchecks the input is unique or all equalmpcombines the two checks together.
Reflection
I'm not happy with how long this is.
(=:)needs a prefix. It is absurd that this doesn't exist. A 3-byte prefix would save me bytes here, but really a 2-byte prefix is what this needs.- I hate having to use
(*|*)here. I should either find a better way to take the logical or of the output of two functions or I should shorten this operation. - I couldn't find
uzat first.unzipshould be added as a deprecated synonym. - This sort of "unique or all equal" (
uq*|*lq) is a strange operation for most purposes, but comes up in card games frequently. Adding a built-in would be easy and could save me in the future. It should definitely be 3-bytes.
Maple, 121 bytes
c->select(x->nops({map2(op,2,x)[]})=3and((e:=nops({map2(op,1,x)[]}))=3or e=1),[seq(c[i],i=combinat:-choose(nops(c),3))]);
Ungolfed:
f:=proc(c) # input e.g. [[W,Y],[F,B],[S,R],[S,R]]
[seq(c[i],i=combinat:-choose(nops(c),3))];# all combinations of 3 cards
select(x->nops({map2(op,2,x)[]})=3 # filter for 3 different colors
and ((e:=nops({map2(op,1,x)[]}))=3 or e=1),%); # and either 1 or 3 elements
end proc;
Vyxal, 14 bytes
3ḋ'∩÷:U⁼$UL2≠*
Ah 2011-2017, much simpler times in life. That time being when I played Club Penguin (ending in 2017 because that's well when Disney decided it'd be a good idea to shut the website down smh). Fun fact you mightn't've known about me: I was an avid IRL Card Jitsu collector (because they made real life Card Jitsu booster packs that were sold in actual brick and mortar stores). I was also black belt on Club Penguin, so this challenge brings back good memories of being young :)
In terms of the code golf (the reason we're here), takes input as a list of [Element, Colour], and outputs as a list of lists of [Element, Colour]. The linked program converts the IO from the challenge body to this format (the header and footer).
Explained
3ḋ'∩÷:U⁼$UL2≠*
3ḋ # Combinations without replacement of length 3
' # Keep combinations where:
∩÷ # (After transposing the combination to have [elements, colours] on the stack)
:U⁼ # The colours are unique
$ * # AND
UL2≠ # There are either 3 unique colours, or 1 unique colour
💎
Created with the help of Luminespire.
Charcoal, 38 bytes
WS⊞υιFLυFιΦE…υκ⁺λ⁺§υκ§υι⬤λ№E⊕№αν⊕⊗π№λν
Try it online! Link is to verbose version of code. Takes input as a list of newline terminated pairs of uppercase letters and other printable ASCII and outputs a list of sets of three cards. Explanation:
WS⊞υι
Read in the cards.
FLυFι
Start enumerating the third and second card of each possible set.
E…υκ⁺λ⁺§υκ§υι
Enumerate all sets of three cards as a single string.
Φ...⬤λ№E⊕№αν⊕⊗π№λν
Filter on those whose characters are unique, unless they are uppercase letters, in which case they may appear exactly 3 times.
Retina, 82 bytes
Lv`[A-C].+
L$wm`(?<=^(..)+)(..)(..)+
$1$2$3
Am`(\d).+\1|([A-C]).+\2.+$(?<!^(\2.)+)
Try it online! Takes input as a string of six characters using A-C to represent elements and any six digits of your choice to represent colours. (I have not been consistent between different test cases.) Explanation:
Lv`[A-C].+
Get all of the even-length suffixes of the input.
L$wm`(?<=^(..)+)(..)(..)+
$1$2$3
Get all of the sets of three cards.
Am`(\d).(..)?\1|([A-C]).+\3.+$(?<!^(\3.)+)
Remove those with repeated digits or those with duplicated but not triplicated letters.