21
\$\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\$
  • 3
    \$\begingroup\$ Can we input/output as a string? For example: "LDLDD" -> "LL DDD" or something like that? \$\endgroup\$ – Comrade SparklePony Jul 11 '17 at 4:54
  • 3
    \$\begingroup\$ Or output perhaps as a list of the two strings, e.g. `"LDLDD" -> ["LL", "DDD"] \$\endgroup\$ – Comrade SparklePony Jul 11 '17 at 7:27
  • \$\begingroup\$ Would also like an answer, as my answer depends on this \$\endgroup\$ – Skidsdev Jul 11 '17 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 '17 at 8:59
  • \$\begingroup\$ No, the output must be an array/list. @ComradeSparklePony \$\endgroup\$ – Amorris Jul 11 '17 at 9:04

34 Answers 34

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\$
  • \$\begingroup\$ Why is it 'DL' but not 'LD'? \$\endgroup\$ – Leaky Nun Jul 11 '17 at 3:28
  • \$\begingroup\$ @LeakyNun: added explanation. It works by removing the wrong character rather than selecting the right one. \$\endgroup\$ – marinus Jul 11 '17 at 3:30
  • 1
    \$\begingroup\$ 'LD'∩⍨¨⊂ or ⍞∘∩¨'LD' may be easier to explain. \$\endgroup\$ – Adám Jul 11 '17 at 6:22
13
\$\begingroup\$

Python 3, 37 bytes

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

Try it online!

\$\endgroup\$
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\$
  • 3
    \$\begingroup\$ As a default I/O rule, you cannot assume input is stored in one variable \$\endgroup\$ – Keyu Gan Jul 11 '17 at 5:00
  • \$\begingroup\$ @KeyuGan argh! Fair enough \$\endgroup\$ – ScottMcGready Jul 11 '17 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 '17 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\$ – Jörg Hülsermann Jul 11 '17 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\$ – ScottMcGready Jul 11 '17 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\$
  • \$\begingroup\$ TIO link (mathics)? \$\endgroup\$ – Leaky Nun Jul 11 '17 at 3:29
  • 1
    \$\begingroup\$ How about Cases@@@{{#,L},{#,D}}&, for 22 bytes? \$\endgroup\$ – Not a tree Jul 11 '17 at 4:31
  • \$\begingroup\$ Great idea, Not a tree! You should post that answer—I'll upvote :) \$\endgroup\$ – Greg Martin Jul 11 '17 at 18:14
  • \$\begingroup\$ Done! \$\endgroup\$ – Not a tree Jul 12 '17 at 2:57
3
\$\begingroup\$

Haskell, 32 bytes

import Data.List
partition(>"K")

Just a boring library function.

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Try with no imports :P \$\endgroup\$ – Amorris Jul 11 '17 at 5:30
3
\$\begingroup\$

Ruby, 26 bytes

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

Try it online!

\$\endgroup\$
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
    \$\begingroup\$ 45 bytes with using -r option instead of -f remove<?php and drop the space after the as \$\endgroup\$ – Jörg Hülsermann Jul 11 '17 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\$
  • 1
    \$\begingroup\$ {#,x} can be #|x for -4 bytes. \$\endgroup\$ – CalculatorFeline Jul 12 '17 at 3:01
  • \$\begingroup\$ @CalculatorFeline, wow, that trick is amazing! Thank you! \$\endgroup\$ – Not a tree Jul 12 '17 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\$ – CalculatorFeline Jul 12 '17 at 15:34
  • \$\begingroup\$ You can also use . and arithmetic operators. \$\endgroup\$ – CalculatorFeline Jul 27 '17 at 17:38
  • \$\begingroup\$ Also, precedence abuse has more savings for you (with an output format change): #.L|#.D \$\endgroup\$ – CalculatorFeline Jul 27 '17 at 19:51
2
\$\begingroup\$

Java 8, 105 bytes

import java.util.stream.*;a->Stream.of(a).collect(Collectors.groupingBy("D"::equals)).values().toArray();

Tips welcome.


New to PPCG, do I have to include import java.util.*;import java.util.stream.*; in the byte count?


Non-competing, it doesn't create empty lists with an empty input. Thanks to Nevay for saving some bytes.

\$\endgroup\$
  • 2
    \$\begingroup\$ Imports do have to be counted, or you can fully-qualify your class names if that is shorter. \$\endgroup\$ – user18932 Jul 12 '17 at 1:24
  • 1
    \$\begingroup\$ You can use Stream#of instead of Arrays#stream to reduce the imports to java.util.stream.* and "D"::equals instead of k->k.equals("D"). Besides that the code doesn't meet the requirements as it does not output an empty list if no L/D is present (test-cases 2-4). \$\endgroup\$ – Nevay Jul 12 '17 at 8:31
  • \$\begingroup\$ Welcome to PPCG! Unfortunately, invalid answers cannot be marked as non-competing. You're welcome to modify this answer to make it valid, but for now, it should be deleted. (You should probably delete it yourself; if a mod deletes it, you can't undelete it yourself once you have a working solution.) \$\endgroup\$ – Esolanging Fruit Jul 16 '17 at 4:31
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\$
  • 1
    \$\begingroup\$ l('L'). is 5 bytes shorter than l(X):-X='L'. \$\endgroup\$ – Fatalize Jul 25 '17 at 13:05
  • \$\begingroup\$ @Fatalize - thanks! Edited in. \$\endgroup\$ – TessellatingHeckler Jul 25 '17 at 16:34
2
\$\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\$
  • \$\begingroup\$ "Hmm, removing the ¥ should work..." [["L","L","D","D"],[]] "Nope, not going there :)" - me 2017 \$\endgroup\$ – ETHproductions Jul 11 '17 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 '17 at 13:15
1
\$\begingroup\$

Pyth, 10 9 bytes

mc@dQ1"LD

Test suite.

\$\endgroup\$
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\$
  • \$\begingroup\$ @Leo Hmm, you may be right...fixed. \$\endgroup\$ – Erik the Outgolfer Jul 11 '17 at 10:37
  • \$\begingroup\$ It seems Jelly input is different from Jelly output? Does the interpreter do string->char[] automagically? \$\endgroup\$ – nmjcman101 Jul 11 '17 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\$ – Erik the Outgolfer Jul 11 '17 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
    \$\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 '17 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\$
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\$
0
\$\begingroup\$

Perl 5, 70 bytes

$"='","';@L=(L)x y/L//;@D=(D)x y/D//;$_="[[\"@L\"],[\"@D\"]]";s/""//g

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.