Help me do my washing

21

1

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"]]

[] -> [[],[]]

aimorris

Posted 2017-07-11T03:18:53.020

Reputation: 1 217

3Can we input/output as a string? For example: "LDLDD" -> "LL DDD" or something like that? – Comrade SparklePony – 2017-07-11T04:54:20.253

3Or output perhaps as a list of the two strings, e.g. `"LDLDD" -> ["LL", "DDD"] – Comrade SparklePony – 2017-07-11T07:27:11.780

Would also like an answer, as my answer depends on this – Skidsdev – 2017-07-11T08:46:43.997

How about mixed output? As in an array containing one string and one array of strings? e.g., ["L","L",["D","D","D"]]. – Shaggy – 2017-07-11T08:59:43.993

No, the output must be an array/list. @ComradeSparklePony – aimorris – 2017-07-11T09:04:41.160

Is it acceptable to take a string as input e.g. 'LDLDD' instead of ['L', 'D', 'L', 'D', 'D']? – Erik the Outgolfer – 2017-07-11T09:45:02.123

@EriktheOutgolfer No the input must be an array/list. However, I would presume in most languages it would be easy to convert an array of string to a string? – aimorris – 2017-07-11T09:48:15.953

@Amorris Yeah it should probably. – Erik the Outgolfer – 2017-07-11T09:49:47.127

@EriktheOutgolfer After all, a string is an array of characters... – aimorris – 2017-07-11T10:03:28.170

Welp, that's braingolf out then. Can't do nested arrays – Skidsdev – 2017-07-11T10:26:05.657

@Amorris what about 2 separate Arrays (IE [L, L], [D, D, D]) as opposed to an array of arrays? – Skidsdev – 2017-07-11T10:26:59.510

@Mayube Sure thats fine, not sure how your gonna get that in one output though... – aimorris – 2017-07-11T10:31:54.270

Answers

12

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'~⍨¨⊂) ''
┌┬┐
│││
└┴┘

marinus

Posted 2017-07-11T03:18:53.020

Reputation: 30 224

Why is it 'DL' but not 'LD'? – Leaky Nun – 2017-07-11T03:28:45.403

@LeakyNun: added explanation. It works by removing the wrong character rather than selecting the right one. – marinus – 2017-07-11T03:30:35.213

1'LD'∩⍨¨⊂ or ⍞∘∩¨'LD' may be easier to explain. – Adám – 2017-07-11T06:22:33.663

13

Python 3, 37 bytes

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

Try it online!

Leaky Nun

Posted 2017-07-11T03:18:53.020

Reputation: 45 011

5

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.

xnor

Posted 2017-07-11T03:18:53.020

Reputation: 115 687

4

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);

ScottMcGready

Posted 2017-07-11T03:18:53.020

Reputation: 141

3As a default I/O rule, you cannot assume input is stored in one variable – Keyu Gan – 2017-07-11T05:00:58.960

@KeyuGan argh! Fair enough – ScottMcGready – 2017-07-11T05:44:21.440

2Use 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 – Ezenhis – 2017-07-11T09:28:34.300

1using 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); – Jörg Hülsermann – 2017-07-11T11:26:18.793

My first golf attempt after years lurking and I'm still a total amateur! Thanks for the feedback (and up-votes) though everyone :)! – ScottMcGready – 2017-07-11T23:02:43.463

3

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.)

Greg Martin

Posted 2017-07-11T03:18:53.020

Reputation: 13 940

TIO link (mathics)? – Leaky Nun – 2017-07-11T03:29:04.130

1How about Cases@@@{{#,L},{#,D}}&, for 22 bytes? – Not a tree – 2017-07-11T04:31:59.823

Great idea, Not a tree! You should post that answer—I'll upvote :) – Greg Martin – 2017-07-11T18:14:14.450

Done! – Not a tree – 2017-07-12T02:57:09.840

3

Haskell, 32 bytes

import Data.List
partition(>"K")

Just a boring library function.

Try it online!

nimi

Posted 2017-07-11T03:18:53.020

Reputation: 34 639

1Try with no imports :P – aimorris – 2017-07-11T05:30:01.863

3

Ruby, 26 bytes

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

Try it online!

canhascodez

Posted 2017-07-11T03:18:53.020

Reputation: 201

2

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]

TessellatingHeckler

Posted 2017-07-11T03:18:53.020

Reputation: 2 412

1l('L'). is 5 bytes shorter than l(X):-X='L'. – Fatalize – 2017-07-25T13:05:53.207

@Fatalize - thanks! Edited in. – TessellatingHeckler – 2017-07-25T16:34:50.473

2

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)) 

Renzo

Posted 2017-07-11T03:18:53.020

Reputation: 2 260

2

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.

Ezenhis

Posted 2017-07-11T03:18:53.020

Reputation: 191

145 bytes with using -r option instead of -f remove<?php and drop the space after the as – Jörg Hülsermann – 2017-07-11T11:18:10.823

2

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.

Shaggy

Posted 2017-07-11T03:18:53.020

Reputation: 24 623

"Hmm, removing the ¥ should work..." [["L","L","D","D"],[]] "Nope, not going there :)" - me 2017 – ETHproductions – 2017-07-11T13:13:05.573

@ETHproductions: Ha-ha! Yeah, I tried so many ways to try to get it to work without the ¥. – Shaggy – 2017-07-11T13:15:05.123

2

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.

Justin

Posted 2017-07-11T03:18:53.020

Reputation: 417

2Imports do have to be counted, or you can fully-qualify your class names if that is shorter. – None – 2017-07-12T01:24:34.903

1You 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). – Nevay – 2017-07-12T08:31:57.147

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.) – Esolanging Fruit – 2017-07-16T04:31:02.683

2

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)

Majora320

Posted 2017-07-11T03:18:53.020

Reputation: 233

2

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]}&.

Not a tree

Posted 2017-07-11T03:18:53.020

Reputation: 3 106

1{#,x} can be #|x for -4 bytes. – CalculatorFeline – 2017-07-12T03:01:18.200

@CalculatorFeline, wow, that trick is amazing! Thank you! – Not a tree – 2017-07-12T03:10:56.240

1@@ and @@@ work with any head, not just List. If | doesn't work, you can still save in some cases with &&, ||, or **. – CalculatorFeline – 2017-07-12T15:34:36.667

You can also use . and arithmetic operators. – CalculatorFeline – 2017-07-27T17:38:16.950

Also, precedence abuse has more savings for you (with an output format change): #.L|#.D – CalculatorFeline – 2017-07-27T19:51:28.890

@CalculatorFeline, I can't get that to work without brackets, and Cases@@@(#.L|#.D)& is no shorter than the current answer. What version of Mathematica are you using? – Not a tree – 2017-07-28T02:27:56.323

Oh yeah I forgot about that X( – CalculatorFeline – 2017-07-30T00:43:30.297

1

Pyth, 10 9 bytes

mc@dQ1"LD

Test suite.

Leaky Nun

Posted 2017-07-11T03:18:53.020

Reputation: 45 011

Using .g seems to be shorter.

– FryAmTheEggman – 2017-07-11T03:56:33.433

1

05AB1E, 8 bytes

'Lù'DÃ)

Try it online!

kalsowerus

Posted 2017-07-11T03:18:53.020

Reputation: 1 894

1

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"]))

Herman L

Posted 2017-07-11T03:18:53.020

Reputation: 3 611

1

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

Kevin Cruijssen

Posted 2017-07-11T03:18:53.020

Reputation: 67 575

1You 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) – Nevay – 2017-07-11T13:27:29.113

1

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();
    }
}

TheLethalCoder

Posted 2017-07-11T03:18:53.020

Reputation: 6 930

1

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.

user20151

Posted 2017-07-11T03:18:53.020

Reputation:

1

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.

Erik the Outgolfer

Posted 2017-07-11T03:18:53.020

Reputation: 38 134

@Leo Hmm, you may be right...fixed. – Erik the Outgolfer – 2017-07-11T10:37:02.563

It seems Jelly input is different from Jelly output? Does the interpreter do string->char[] automagically? – nmjcman101 – 2017-07-11T12:28:38.713

1@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. – Erik the Outgolfer – 2017-07-11T12:29:15.810

1

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.

faso

Posted 2017-07-11T03:18:53.020

Reputation: 141

1

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

Leo

Posted 2017-07-11T03:18:53.020

Reputation: 8 482

1

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.

beaker

Posted 2017-07-11T03:18:53.020

Reputation: 2 349

1

R, 35 bytes

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

Try it online!

Reads from stdin.

Giuseppe

Posted 2017-07-11T03:18:53.020

Reputation: 21 077

1

Julia, 26 bytes

g(s)=s[s.=="L"],s[s.=="D"]

Tanj

Posted 2017-07-11T03:18:53.020

Reputation: 199

0

Haskell (Lambdabot), 41 bytes

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

Try it online!

ბიმო

Posted 2017-07-11T03:18:53.020

Reputation: 15 345

0

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.

TessellatingHeckler

Posted 2017-07-11T03:18:53.020

Reputation: 2 412

0

Retina, 21 11 bytes

-10 bytes thanks to CalculatorFeline

O^`.
LD
L D

Try it online!

ovs

Posted 2017-07-11T03:18:53.020

Reputation: 21 408

The 21 byte version can be O^\.LDL D`. – CalculatorFeline – 2017-07-12T03:02:24.583

0

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"]

Esolanging Fruit

Posted 2017-07-11T03:18:53.020

Reputation: 13 542

0

Perl 5, 70 bytes

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

Try it online!

Xcali

Posted 2017-07-11T03:18:53.020

Reputation: 7 671

0

Javascript, 38 bytes

q=>['L','D'].map(x=>q.filter(y=>x==y))

Coert Grobbelaar

Posted 2017-07-11T03:18:53.020

Reputation: 131

2Hello and welcome to the site! We do not allow answers that assume a variable as input, we call these snippets. Instead format your answer as a function (named on unnamed), or a full program with IO. – Post Rock Garf Hunter – 2017-10-02T06:47:02.030

Thanks @FunkyComputerMan. I edited it, let me know if it is correct. – Coert Grobbelaar – 2017-10-02T11:10:14.183

0

J, 13 bytes

<@-."1 0&'DL'

Try it online!

FrownyFrog

Posted 2017-07-11T03:18:53.020

Reputation: 3 112

0

Ruby, 20 bytes

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

Try it online!

G B

Posted 2017-07-11T03:18:53.020

Reputation: 11 099