23
\$\begingroup\$

Help! My Completely Automated Lights From Darks Separator V3001.01 broke! :(

Guidelines


Task

Write a program that will take an input of an array (or a list in some languages) of any amount of strings that are either the letter L or the letter D (representing lights or darks) and output an array that contains two arrays, one with all the L's, and one with all the D's.


Rules

  • It's code golf so the shortest answer in bytes wins
  • Input will only ever contain capitals
  • There must be the same number of L's in the output as there is in the input, same goes for the D's
  • The input may only have one element (or maybe even zero elements)
  • If one or both of the output arrays contain no elements, output an empty list (in some languages this may mean you need to output a string)
  • Always have the first array be the array of L's

Example output:

["L","D","L","D","D"] -> [["L","L"],["D","D","D"]]

["L","L","L"] -> [["L","L","L"],[]]

["D","D"] -> [[],["D","D"]]

[] -> [[],[]]

\$\endgroup\$
12
  • 4
    \$\begingroup\$ Can we input/output as a string? For example: "LDLDD" -> "LL DDD" or something like that? \$\endgroup\$
    – sporkl
    Jul 11, 2017 at 4:54
  • 4
    \$\begingroup\$ Or output perhaps as a list of the two strings, e.g. `"LDLDD" -> ["LL", "DDD"] \$\endgroup\$
    – sporkl
    Jul 11, 2017 at 7:27
  • \$\begingroup\$ Would also like an answer, as my answer depends on this \$\endgroup\$
    – Mayube
    Jul 11, 2017 at 8:46
  • \$\begingroup\$ How about mixed output? As in an array containing one string and one array of strings? e.g., ["L","L",["D","D","D"]]. \$\endgroup\$
    – Shaggy
    Jul 11, 2017 at 8:59
  • \$\begingroup\$ No, the output must be an array/list. @ComradeSparklePony \$\endgroup\$
    – aimorris
    Jul 11, 2017 at 9:04

35 Answers 35

13
\$\begingroup\$

Python 3, 37 bytes

lambda a:[[c]*a.count(c)for c in"LD"]

Try it online!

\$\endgroup\$
12
\$\begingroup\$

APL, 8 bytes

'DL'~⍨¨⊂

Explanation:

  • : enclosed input
  • ~⍨¨: without each
  • 'DL': 'D' and 'L'

Examples:

      ('DL'~⍨¨⊂) 'LDLDD'
┌──┬───┐
│LL│DDD│
└──┴───┘
      ('DL'~⍨¨⊂) 'LLL'
┌───┬┐
│LLL││
└───┴┘
      ('DL'~⍨¨⊂) 'DD'
┌┬──┐
││DD│
└┴──┘
      ('DL'~⍨¨⊂) ''
┌┬┐
│││
└┴┘
\$\endgroup\$
3
  • \$\begingroup\$ Why is it 'DL' but not 'LD'? \$\endgroup\$
    – Leaky Nun
    Jul 11, 2017 at 3:28
  • \$\begingroup\$ @LeakyNun: added explanation. It works by removing the wrong character rather than selecting the right one. \$\endgroup\$
    – marinus
    Jul 11, 2017 at 3:30
  • 1
    \$\begingroup\$ 'LD'∩⍨¨⊂ or ⍞∘∩¨'LD' may be easier to explain. \$\endgroup\$
    – Adám
    Jul 11, 2017 at 6:22
5
\$\begingroup\$

Haskell, 28 bytes

f l=[filter(==[c])l|c<-"LD"]

Try it online!

If the input can be a list of characters, the [] around c can be removed.

\$\endgroup\$
4
\$\begingroup\$

PHP, 46 bytes

Assumed given list is: $arr = ['L','L','D','D','L','D','D','D','D','L'];

foreach($arr as $b){$a[$b][]=$b;};print_r($a);

\$\endgroup\$
5
  • 3
    \$\begingroup\$ As a default I/O rule, you cannot assume input is stored in one variable \$\endgroup\$
    – Keyu Gan
    Jul 11, 2017 at 5:00
  • \$\begingroup\$ @KeyuGan argh! Fair enough \$\endgroup\$ Jul 11, 2017 at 5:44
  • 2
    \$\begingroup\$ Use can use $argv instead of $arr and expect the script to be run from command line as php -f golf.php L L D D L D D D D L - but then again you have to go around $argv[0] which is the file name \$\endgroup\$
    – Ezenhis
    Jul 11, 2017 at 9:28
  • 1
    \$\begingroup\$ using this way the shortest solutions are for(;$b=$argv[++$i];)$a[$b][]=$b;print_r($a); or <?foreach($_GET as$b)$a[$b][]=$b;print_r($a); \$\endgroup\$ Jul 11, 2017 at 11:26
  • \$\begingroup\$ My first golf attempt after years lurking and I'm still a total amateur! Thanks for the feedback (and up-votes) though everyone :)! \$\endgroup\$ Jul 11, 2017 at 23:02
3
\$\begingroup\$

Mathematica, 27 bytes

Rest/@Gather[{L,D}~Join~#]&

Pure function taking a list of Ls and Ds (symbols, not characters/strings) as input and returning a list of two lists. For example,

Rest/@Gather[{L,D}~Join~#]& @ {D, L, L, D, L}

returns {{L, L, L}, {D, D}}. Try it online!

Gather by itself is close to what we want, but fails to meet the spec in two ways: it doesn't produce empty lists if the input is missing Ls or Ds, and it doesn't always sort Ls to the left. Replacing the input # with {L,D}~Join~# solves both problems at once: it means there will be at least one L and at least one D, and the Ls will be returned first since an L was encountered first. Rest/@ then removes the initial L and D.

(I tried a solution using Count, but due to currying issues, it didn't seem to be shorter: ±q_:=#~Table~Count[q,#]&/@{L,D} is 31 bytes.)

\$\endgroup\$
4
  • \$\begingroup\$ TIO link (mathics)? \$\endgroup\$
    – Leaky Nun
    Jul 11, 2017 at 3:29
  • 1
    \$\begingroup\$ How about Cases@@@{{#,L},{#,D}}&, for 22 bytes? \$\endgroup\$
    – Not a tree
    Jul 11, 2017 at 4:31
  • \$\begingroup\$ Great idea, Not a tree! You should post that answer—I'll upvote :) \$\endgroup\$ Jul 11, 2017 at 18:14
  • \$\begingroup\$ Done! \$\endgroup\$
    – Not a tree
    Jul 12, 2017 at 2:57
3
\$\begingroup\$

Haskell, 32 bytes

import Data.List
partition(>"K")

Just a boring library function.

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Try with no imports :P \$\endgroup\$
    – aimorris
    Jul 11, 2017 at 5:30
3
\$\begingroup\$

Ruby, 26 bytes

->x{x.partition{|e|e==?L}}

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Japt, 13 12 10 bytes

2Æf¥"LD"gX

Test it (-Q flag for visualisation purposes only)


Explanation

Implicit input of array U.

Generate the array [0,1] and pass each element through a function, with X being the current element.

Filter U by checking for equality...

"LD"gX

...with the character in string LD at index X.

\$\endgroup\$
2
  • \$\begingroup\$ "Hmm, removing the ¥ should work..." [["L","L","D","D"],[]] "Nope, not going there :)" - me 2017 \$\endgroup\$ Jul 11, 2017 at 13:13
  • \$\begingroup\$ @ETHproductions: Ha-ha! Yeah, I tried so many ways to try to get it to work without the ¥. \$\endgroup\$
    – Shaggy
    Jul 11, 2017 at 13:15
2
\$\begingroup\$

PHP7, 52 45 bytes

-7 bytes thanks to @Jörg Hülsermann

foreach($argv as$a)$$a[]=$a;print_r([$L,$D]);

Use with CLI as php -r a.php L L L D D L D

The script goes through the provided arguments and appends them to an array based on its value.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 45 bytes with using -r option instead of -f remove<?php and drop the space after the as \$\endgroup\$ Jul 11, 2017 at 11:18
2
\$\begingroup\$

Common Lisp, 66 65 bytes

(defun f(x)`(,(remove"D"x :test'equal),(remove"L"x :test'equal)))

Try it online!

If, instead of strings, we use symbols, then it is much shorter:

Common Lisp, 42 41 40 bytes

(defun f(x)(mapcar'remove'(D L)`(,x,x)))

Try it online!

(f '(D D L L D L D)) ; => ((L L L) (D D D D)) 
\$\endgroup\$
2
\$\begingroup\$

Racket, 48 bytes

(compose list((curry partition)(λ(x)(eq? x'L))))

Just apply this anonymous function to, e.g., '(L D L D D L)

\$\endgroup\$
2
\$\begingroup\$

Mathematica, 22 18 bytes

4 bytes saved by the genius of CalculatorFeline!

Cases@@@{#|L,#|D}&

Try it online, or at the Wolfram sandbox!

Input is a list of the symbols L and D — not strings, just the letters on their own, like in Greg Martin's answer. The syntax #|L is shorthand for Alternatives[#,L], but the @@@ syntax replaces the head Alternatives with Cases, so this code is equivalent to {Cases[#,L],Cases[#,D]}&.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ {#,x} can be #|x for -4 bytes. \$\endgroup\$ Jul 12, 2017 at 3:01
  • \$\begingroup\$ @CalculatorFeline, wow, that trick is amazing! Thank you! \$\endgroup\$
    – Not a tree
    Jul 12, 2017 at 3:10
  • 1
    \$\begingroup\$ @@ and @@@ work with any head, not just List. If | doesn't work, you can still save in some cases with &&, ||, or **. \$\endgroup\$ Jul 12, 2017 at 15:34
  • \$\begingroup\$ You can also use . and arithmetic operators. \$\endgroup\$ Jul 27, 2017 at 17:38
  • \$\begingroup\$ Also, precedence abuse has more savings for you (with an output format change): #.L|#.D \$\endgroup\$ Jul 27, 2017 at 19:51
2
\$\begingroup\$

Prolog (SWI), 42, 37 bytes

l('L').
w(L,D,W):-partition(l,W,L,D).

Try it online!

Given that W is a list of washing, w/3 will unify L and D into lists of Lights and Darks respectively, by partitioning the washing against a predicate which succeeds if an item is a Light.

[Edit: golfed -5 thanks to Fatalize]

\$\endgroup\$
2
  • 1
    \$\begingroup\$ l('L'). is 5 bytes shorter than l(X):-X='L'. \$\endgroup\$
    – Fatalize
    Jul 25, 2017 at 13:05
  • \$\begingroup\$ @Fatalize - thanks! Edited in. \$\endgroup\$ Jul 25, 2017 at 16:34
1
\$\begingroup\$

Pyth, 10 9 bytes

mc@dQ1"LD

Test suite.

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

05AB1E, 8 bytes

'Lù'DÃ)

Try it online!

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

Javascript (ES6), 37 bytes

This is based on a (now deleted) Javascript (ES6) answer.

a=>[(b=c=>a.filter(d=>c==d))`L`,b`D`]

Ungolfed version:

function(array) {
  function filter(character){
    return array.filter(function(d) {
      return character == d;
    });
  }
  return [filter("L"), filter("D")];
}

Example code snippet:

f=

a=>[(b=c=>a.filter(d=>c==d))`L`,b`D`]

console.log(f(["L", "D", "L", "D", "D"]))

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

C#, 61 bytes

using System.Linq;a=>new[]{a.Where(c=>c<69),a.Where(c=>c>68)}

Full/Formatted Version:

using System;
using System.Linq;

class P
{
    static void Main()
    {
        Func<char[], System.Collections.Generic.IEnumerable<char>[]> f =
            a => new[] { a.Where(c => c < 69), a.Where(c => c > 68) };

        Console.WriteLine(string.Join(", ", f(new[]{ 'L', 'D', 'L', 'D', 'D' }).SelectMany(a => a.Select(c => c))));

        Console.ReadLine();
    }
}
\$\endgroup\$
1
\$\begingroup\$

F#, 37 bytes

let f s=List.partition(fun a->a="L")s

Try it online!

Takes input as a list of strings, and returns two lists, the first with elements where fun a -> a="L" is true and the other with elements that result in false.

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

Jelly, 10 bytes

ẎfЀ⁾LDW€€

Try it online!

In Jelly a string is a list of 1-char Python strings, e.g. ['a', 'b', 'c']. That's why you get output such as [[['L'], ['L']], [['D'], ['D'], ['D']]], since 1-char Jelly strings behave the same.

Doesn't work as a full program, hence the ÇŒṘ at the bottom.

\$\endgroup\$
3
  • \$\begingroup\$ @Leo Hmm, you may be right...fixed. \$\endgroup\$ Jul 11, 2017 at 10:37
  • \$\begingroup\$ It seems Jelly input is different from Jelly output? Does the interpreter do string->char[] automagically? \$\endgroup\$
    – nmjcman101
    Jul 11, 2017 at 12:28
  • 1
    \$\begingroup\$ @nmjcman101 On strings it's different, since input is in Python format and output is in Jelly format. That's why I need the W€€ part. \$\endgroup\$ Jul 11, 2017 at 12:29
1
\$\begingroup\$

Perse, 21 bytes

part(i,fn(x){x=="L"})

I may or may not have implemented the list partition function specifically for this challenge. Takes the input as an array of strings.

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

Husk, 7 bytes

Mof-"DL

Try it online!

Explanation

Mof-"DL
M   "DL    For each character in ['D','L']:
 of-         keep only those strings that are not empty if that character is removed
\$\endgroup\$
1
\$\begingroup\$

Java 8, 110 106 bytes

a->{String[]r={"",""};for(char c:a)r[c/69]+=c;return new char[][]{r[1].toCharArray(),r[0].toCharArray()};}

-4 bytes thanks to @Nevay.

Explanation:

Try it here.

a->{                      // Method with char-array parameter and 2D char-array return-type
  String[]r={"",""};      //  Two Strings in an array
  for(char c:a)           //  Loop over the characters of the input
    r[c/69]+=c;           //   Append either of the two String with the character
                          //   c/69 will result in 0 for 'D' and 1 for 'L'
                          //  End of loop (implicit / single-line body)
  return new char[][]{    //  Return a 2D character-array
    r[1].toCharArray(),   //   With the String for L's converted to a char-array
    r[0].toCharArray()};  //   and String D's converted to a char-array
}                         // End of method
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can store l and d in an array to remove the if-else statement. a->{String[]r={"",""};for(char c:a)r[c/69]+=c;return new char[][]{r[1].toCharArray(),r[0].toCharArray()};} (-4 bytes) \$\endgroup\$
    – Nevay
    Jul 11, 2017 at 13:27
1
\$\begingroup\$

Octave, 21 bytes

@(A){A(a=A>72),A(~a)}

Input is an array of characters, output is a cell array. Recycled from my answer here.

Sample execution on ideone.

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

R, 35 bytes

x=scan(,'');list(x[i<-x>'D'],x[!i])

Try it online!

Reads from stdin.

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

Julia, 26 bytes

g(s)=s[s.=="L"],s[s.=="D"]
\$\endgroup\$
1
\$\begingroup\$

Ruby, 20 bytes

->l{[l-[?D],l-[?L]]}

Try it online!

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

Thunno 2, 8 bytes

`LDdẊcx×

Try it online!

Explanation

`LDdẊcx×  # Implicit input                   ->  ["L","D","L","D","D"]
`LD       # Push the string "LD"             ->  ["L","D","L","D","D"]  "LD"
   d      # Split it into characters         ->  ["L","D","L","D","D"]  ["L","D"]
    Ẋ     # Store it in x without popping    ->  ["L","D","L","D","D"]  ["L","D"]
     c    # Count occurrences in the input   ->  [2,3]
      x×  # Multiply by x elementwise        ->  [["L","L"],["D","D","D"]]
          # Implicit output
\$\endgroup\$
0
\$\begingroup\$

Haskell (Lambdabot), 41 bytes

reverse.map tail.group.sort.("LD"++).join

Try it online!

\$\endgroup\$
0
\$\begingroup\$

PowerShell, 27 bytes

($args-eq'L'),($args-eq'D')

Try it online!


Edit: previously $args.where({$_-eq'L'},'sp') for 28 bytes. Could be $args.where({+"0x$_"},'sp') for 27 if not for the rule that L's must come first.

\$\endgroup\$
0
\$\begingroup\$

CJam, 14 bytes

"LD"qf{1$e=*}`

Input is a list of characters (string), output is a list of lists of characters (list of strings).

Try it online!

Explanation:

"LD"  e# Push the string "LD"                  | "LD"
q     e# Push the input                        | "LD" "LDLLDLDDL"
f{    e# Foreach char in "LD", push input and: | ['L "LDLLDLDDL"
  1$  e#   Copy from 1 back                    | ['L "LDLLDLDDL" 'L
  e=  e#   Count occurences                    | ['L 5
  *   e#   Repeat character                    | ["LLLLL"
}     e# End                                   | ["LLLLL" "DDDD"]
`     e# Stringify:                            | "[\"LLLLL\" \"DDDD\"]"
e# Implicit output: ["LLLLL" "DDDD"]
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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