24
\$\begingroup\$

You're a chef and you love cooking with your spices, but recently you've taken a liking to organizing your spices based on how often you use them. But you have no time to be writing down when you used your spice last. Simply, you swap and move spices around, and this seems to do the trick.

But of course you're a chef and that means you have some cooks with you. You decide to tell them the simple rules of engagement with your spices.

  1. If you recently used a spice, move it up one in the spice rack

  2. If you didn't use any spices at all, e.g. [] empty movement list, then the spice list is not affected.

  3. You may put any spice into my spice holder, but if you use it, make sure to move it.

  4. The list can contain anything. But because these are spices we are working with. It is preferred that you use names of spices.

  5. Spices should be unique. Too many of the same spices spoil the broth... or however that saying goes

Normal code-golf rules apply.

Example of Oregano being used again and again.

pepper  pepper  pepper  pepper  oregano
paprika paprika paprika oregano pepper
salt    salt    oregano paprika paprika
cumin   oregano salt    salt    salt
oregano cumin   cumin   cumin   cumin

Task

Input a list of spices, and a list of what spices got used, then output the final list.

Example

Input

[pepper, paprika, salt, cumin, oregano], [oregano, cumin, cumin, salt, salt, salt]

Output

[salt, pepper, paprika, cumin, oregano]

How this looks

pepper  pepper  pepper  pepper  pepper  pepper  salt
paprika paprika paprika paprika paprika salt    pepper
salt    salt    salt    cumin   salt    paprika paprika
cumin   oregano cumin   salt    cumin   cumin   cumin
oregano cumin   oregano oregano oregano oregano oregano

Input

[pepper, paprika, salt, cumin, oregano], [salt, salt, salt, salt, salt, salt, salt, salt, salt, salt, salt, salt, oregano]

Output

[salt, pepper, paprika, oregano, cumin]
\$\endgroup\$
  • \$\begingroup\$ Is items in list of spices unique? \$\endgroup\$ – tsh Aug 31 '17 at 2:04
  • \$\begingroup\$ Yes, they will be unique \$\endgroup\$ – tisaconundrum Aug 31 '17 at 2:14
  • 31
    \$\begingroup\$ I got pretty far doing this in Chef but eventually it got too tiring! I'll give someone 50 bounty if they can do it. \$\endgroup\$ – geokavel Aug 31 '17 at 5:05
  • 5
    \$\begingroup\$ Here's a gist of getting the input into the mixing bowls. The rest will be very difficult, but doable for the right person! \$\endgroup\$ – geokavel Aug 31 '17 at 6:01
  • 1
    \$\begingroup\$ @geokavel Challenge accepted \$\endgroup\$ – NieDzejkob Sep 7 '17 at 18:15

12 Answers 12

4
\$\begingroup\$

Husk, 15 14 bytes

Fλṁ↔`C⁰tMo→=¢⁰

Inputs are lists of strings (it also works on other kinds of lists). Try it online!

-1 byte thanks to H.PWiz

Explanation

Fλṁ↔`C⁰tMo→=¢⁰  Implicit inputs (two lists).
F               Fold second input using the first as initial value
 λ              with this anonymous function:
                 Arguments x (list of spices) and s (used spice).
                 For example, x=["a","b","c","d"] and s="c".
            ¢⁰   Repeat x infinitely: ["a","b","c","d","a","b","c","d"..
        M        For each item,
           =     test equality to s: [0,0,1,0,0,0,1,0..
         o→      and increment: [1,1,2,1,1,1,2,1..
       t         Drop first element: [1,2,1,1,1,2,1..
    `C⁰          Cut x to these lengths: [["a"],["b","c"],["d"]]
  ṁ↔             Reverse each slice and concatenate: ["a","c","b","d"]

I have to repeat x infinitely, since otherwise the list would lose its last element when we use the topmost spice. It would be enough to add a trailing 1, but repetition takes fewer bytes. A better way would be to rotate the list instead of dropping its first element, but Husk has no built-in for that.

\$\endgroup\$
  • \$\begingroup\$ Σm is for one byte. \$\endgroup\$ – H.PWiz Aug 31 '17 at 13:47
8
\$\begingroup\$

Haskell, 48 bytes

foldl(?) is an anonymous function taking two list arguments and returning a list, with all elements of the same (Eq-comparable) type.

Use as foldl(?)["pepper", "paprika", "salt", "cumin", "oregano"]["oregano", "cumin", "cumin", "salt", "salt", "salt"].

foldl(?)
(x:y:r)?n|y==n=y:x:r|s<-y:r=x:s?n
s?n=s

Try it online!

  • foldl(?) s m starts with the (spice rack) list s and combines it with each element (spice) from m in order, using the operator ?.
  • s?n uses the spice n from the spice rack s and returns the resulting spice rack.
    • If s has at least two elements, ? checks whether the second one is equal to n, and if so switches the first two elements. If not equal, ? keeps the first element fixed and recurses on the rest.
    • If s has at most one element, ? returns it unchanged.
\$\endgroup\$
7
+50
\$\begingroup\$

Chef, 875 843 bytes

S.

Ingredients.
1 g T
0 g Z
J
I

Method.
Put Z into mixing bowl.Take I from refrigerator.B I.Put I into mixing bowl.Take I from refrigerator.B until bed.Take I from refrigerator.V I.Put Z into 2nd mixing bowl.N T.Fold J into mixing bowl.Put J into mixing bowl.Remove I.Fold T into mixing bowl.Put J into 2nd mixing bowl.N until ned.Fold T into mixing bowl.Put T into mixing bowl.Fold J into 2nd mixing bowl.Put J into mixing bowl.C T.Stir for 1 minute.Put Z into mixing bowl.Fold T into mixing bowl.C until ced.Fold T into 2nd mixing bowl.G T.Put T into mixing bowl.Fold T into 2nd mixing bowl.G until ged.Put I into mixing bowl.Fold T into mixing bowl.Take I from refrigerator.V until ved.Fold T into mixing bowl.L T.Put T into 2nd mixing bowl.Fold T into mixing bowl.L until led.Pour contents of 2nd mixing bowl into baking dish.

Serves 1.

-32 bytes thanks to Jonathan Allan by removing the where I wouldn't think it will work.

Chef has no string types, so the ingredients are positive integers. 0 is used to separate the starting list from used ingredients and to end the used ingredients list. See the TIO link for an example.

Pseudocode explaination:

A, B: stack
T, J, IN: int
T = 1
A.push(0) // used as the marker for the bottom of the stack
IN = input() // input the first list
while(IN):
    A.push(IN)
    IN = input()
IN = input() // for each used ingredient
while(IN):
    B.push(0)
    while(T): // move all ingredients up to and including the one we are moving right now to the second stack
        T = A.peek() - IN
        B.push(A.pop())
    A.push(B.pop())
    if(A.peekUnderTop() != 0):
        A.swapTopTwoItems()
    T = B.pop() // move the ingredients from the second stack back to the first
    while(T):
        A.push(T)
        T = B.pop()
    T = IN // to make it non-zero for next iteration
    IN = input(0
print(A.inverted())

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Awesome! Has this language been on TIO all along? \$\endgroup\$ – geokavel Sep 7 '17 at 20:02
  • \$\begingroup\$ By removing some redundant words you can save 32 bytes \$\endgroup\$ – Jonathan Allan Sep 7 '17 at 20:44
  • \$\begingroup\$ @geokavel it got added yesterday. \$\endgroup\$ – Jonathan Allan Sep 7 '17 at 20:59
  • 1
    \$\begingroup\$ @geokavel Did you pour the contents of the mixing bowl into the baking dish before serving? \$\endgroup\$ – NieDzejkob Sep 8 '17 at 5:00
  • 1
    \$\begingroup\$ @NieDzejkob Did you pour the contents of the mixing bowl into the baking dish before serving? that completely sounds like a comment that would go on the cooking SE and not here :P lol (also a very strange question for cooking if you ask me :P) \$\endgroup\$ – HyperNeutrino Sep 8 '17 at 21:03
6
\$\begingroup\$

JavaScript, 61 bytes

a=>b=>b.map(v=>(p=a.indexOf(v))&&a.splice(p-1,2,a[p],a[p-1]))

Input format:

  • f(list_of_spices)(list_of_what_spices_got_used)
  • two list are array of string

Output:

  • list_of_spices is modified in-place.

f=
a=>b=>b.map(v=>(p=a.indexOf(v))&&a.splice(p-1,2,a[p],a[p-1]))

a = ['pepper', 'paprika', 'salt', 'cumin', 'oregano'];
b = ['salt', 'salt', 'salt', 'salt', 'salt', 'salt', 'salt', 'salt', 'salt', 'salt', 'salt', 'salt', 'oregano'];
f(a)(b);
document.write(JSON.stringify(a))

\$\endgroup\$
5
\$\begingroup\$

Python 2, 72 71 69 bytes

New answer, in the spirit of my original attempt.

r,u=input()
for x in u:i=r.index(x);r.insert(i/~i+i,r.pop(i))
print r

Try it online!

Other solution:

Python 2, 69 bytes

r,u=input()
for x in u:i=r.index(x)-1;r[i:i+2]=r[i:i+2][::-1]
print r

Try it online!

\$\endgroup\$
  • \$\begingroup\$ print(r) -> print r? \$\endgroup\$ – tsh Aug 31 '17 at 7:06
  • 1
    \$\begingroup\$ 69 bytes \$\endgroup\$ – Halvard Hummel Aug 31 '17 at 8:03
4
\$\begingroup\$

Python 2, 80 bytes

def g(r,q):
 for s in q:
  i=r.index(s)
  if i:r[i-1],r[i]=r[i],r[i-1]
 return r

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Some savings: Use tabs to indent the inner block, and assign to r[i-1:i+1]. \$\endgroup\$ – Ørjan Johansen Aug 31 '17 at 6:13
  • \$\begingroup\$ Replacing return by print can save another byte. \$\endgroup\$ – Jonathan Frech Aug 31 '17 at 6:16
4
\$\begingroup\$

Java 8, 87 86 76 bytes

a->b->b.forEach(x->{int i=a.indexOf(x);a.set(i,a.set(i>0?i-1:i,a.get(i)));})

Takes two inputs as ArrayList<String> and modifies the first List instead of returning a new one to save bytes.

-10 bytes thanks to @Nevay.

Explanation:

Try it here.

a->b->{                  // Method with two ArrayList<String> parameters and no return-type
  b.forEach(x->{         //  Loop over the second input-List
    int i=a.indexOf(x);  //   Get the index of the current item in the first input-List
    a.set(i,a.set(       //    Swap items:
      i>0?               //     If the current item is not the top item yet:
       i-1               //      Use the item above it
      :                  //     Else:
       i,                //      Use itself
         a.get(i)));     //     And swap it with the current item
  })                     //  End of loop
                         // End of method (implicit / single-line body)
\$\endgroup\$
  • 1
    \$\begingroup\$ 77 bytes: a->b->b.forEach(x->{int i=a.indexOf(x);a.set(i,a.set(i>0?i-1:i,a.get(i)));}); \$\endgroup\$ – Nevay Aug 31 '17 at 9:43
  • \$\begingroup\$ Java is getting revenge for all the people who made fun of it. \$\endgroup\$ – geokavel Aug 31 '17 at 16:00
2
\$\begingroup\$

05AB1E, 20 18 bytes

vDyk>Ig‚£`U`2(@)X«

Try it online!

Explanation

v                    # for each used spice
 D                   # duplicate current spice order
  yk                 # get the index of the current spice
    >                # increment
     Ig‚             # pair with the number of unique spices
        £            # split the spice list into pieces of these sizes
         `           # split as 2 separate lists to stack
          U          # store the list of spices below the current one in X
           `         # push the current spice and all above separately to stack
            2(@      # swap the second item to the top of the stack
               )     # wrap in a list
                X«   # append the rest of the spices
\$\endgroup\$
2
\$\begingroup\$

C#, 125 117 81 79 bytes

(c,n)=>{foreach(var i in n){var j=c.IndexOf(i);if(j!=0){c[j]=c[--j];c[j]=i;}}};

Try it on .NET Fiddle

golfed off 36 bytes thanks to raznagul

\$\endgroup\$
  • \$\begingroup\$ The answer as it is would be 117 bytes as you are missing the namespace for Array.IndexOf. But there are several ways to make the answer shorter: 1. Use a foreach-loop instead of the for-loop. 2. If c is a List<string> instead of string[] you can directly use c.IndexOf. 3. As c is modified in place you don't need to return it. \$\endgroup\$ – raznagul Sep 1 '17 at 8:49
1
\$\begingroup\$

05AB1E, 16 bytes

vÐyk©DĀ-DUè®ǝyXǝ

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Mathematica, 52 bytes

but it is my first post here so please be kind if counted incorrectly :)

Keys@Sort@Merge[{PositionIndex@#,-Counts@#2},Total]&

And an example:

Keys@Sort@Merge[{PositionIndex@#, -Counts@#2}, Total] &[
    {pepper, paprika, salt, cumin, oregano}
  , {oregano, cumin, cumin, salt, salt, salt}
]

{salt, pepper, paprika, cumin, oregano}

\$\endgroup\$
  • \$\begingroup\$ I'm not a Mathematica expert, but you could probably remove some spaces to save some bytes. \$\endgroup\$ – pajonk Sep 1 '17 at 13:38
  • \$\begingroup\$ @pajonk already counted without them but I should've removed them here too, thanks. \$\endgroup\$ – Kuba Sep 1 '17 at 13:42
0
\$\begingroup\$

CJam, 18 bytes

l~{a\_@#__g-e\}%~`

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.