CodeGolf - Ignore the noise #1

15

1

Instructions

Barry is a not so good backend developer in charge of a small API that should give you information about purchases made in a client's shop. However, he hasn't done a great job and your boss tells you to fix it client-side instead. Ideally you should receive comma-separated values such as 927,2,45,90 which correspond to something like item_id,item_amount,unit_price,total

In this first puzzle we only care about item_id and item_amount but we need the other fields in place to present the problem. Barry sometimes gets things mixed up and returns noise as part of the output, he also gets the order wrong, returning noise, noise, unit_price, total, item_id, item_amount.

Your Task

You need to store in a map (or similar structure) the pairs of item_id and item_amount regardless of whether Barry returns them correctly or not and print each element in a new line in the least number of characters possible. (Storing is not mandatory, we just care about the output)

Sample input (mixed correct and messy formats)

103,2,50,100
106,1,900,900
459,40,150,300,67,2
4,20,30,6000

In other words input will be either a,b,x,x or x,x,x,x,a,b where what we care about is a & b. You need to provide code assuming we have a variable called G (or any other name) with all the lines of csv.

Sample output

103,2
106,1
67,2 //This one was messy
4,20

Tolerance

There is a certain margin for tolerance when it comes to the answer. Answers in similar formats but adhering to the correct values, will also be accepted. Formats like [a,b],(a,b) or {a,b} are valid, but a,b is preferred.

Although the first puzzle had mixed acceptance due to the fact that it was easy and fast to solve, I also felt that some people liked that too. So I'm going to continue making quickgolfs for now

Juan Cortés

Posted 2015-05-18T13:28:26.857

Reputation: 1 356

Will input be always of the format x,x,x,x and x,x,x,x,x,x where x denotes a number? – Spikatrix – 2015-05-18T13:40:16.930

Yes, input will follow one of those two formats, let me clarify – Juan Cortés – 2015-05-18T13:40:54.243

Do we need to submit a program or a function or something else? Also, where all can inputs be taken from? – Spikatrix – 2015-05-18T13:42:33.710

Input will be available from a variable in your code G if possible, or similar depending on your language. – Juan Cortés – 2015-05-18T13:44:36.387

Updated requirements to include the valid formats – Juan Cortés – 2015-05-18T14:05:56.810

What about an output like ["103" "2"]? Would that be considered valid? – Dennis – 2015-05-18T14:16:49.360

Sure, you are removing the noise and getting the values, I don't see why not – Juan Cortés – 2015-05-18T14:18:45.777

3

[tag:quick-golf] is essentially a difficulty tag. Consensus seems to be that we don't want those, so I'm removing that tag for now. If you want difficulty tags to be re-evaluated, please make a meta post for it. But that would be a massive retagging effort, which I think should happen in a coordinated manner, rather than individual users creating arbitrary new tags for it.

– Martin Ender – 2015-05-18T14:36:41.373

I'll just stick to adding it in the title, if that's ok – Juan Cortés – 2015-05-18T14:48:22.353

I have a solution here, but it is too long(97 bytes). :(

– Spikatrix – 2015-05-18T15:25:27.597

If our language has variables, do we have to assume the input is stored in one? My code would be shorter if I just read from STDIN. The Perl solution is doing this as well. – Dennis – 2015-05-18T15:51:28.057

I dont mind reading from STDIN or equivalent input, whatever is shortest – Juan Cortés – 2015-05-18T15:54:36.507

2@CoolGuy There is no such thing. You're not supposed to beat Pyth with C (because you're never going to). The joy is in beating other submissions in the same language or languages of similar verbosity. If there was already a 50 byte C submission I could understand not posting (although even then, I might post it if the approach is different and interesting). But since there isn't, please do post your answer. You're fairly close to JavaScript and Python, so it's definitely not excessively long for C. – Martin Ender – 2015-05-18T16:05:16.027

@MartinBüttner , Ok. I posted it.

– Spikatrix – 2015-05-20T08:20:07.070

Answers

8

Pyth, 10 bytes

FNG<.<N4 2

Try it online: Pyth Compiler/Executor

(The first 4 chars =G.Q reads all the data and stores it in G)

Explanation

FNG              for row N in G:
    .<N4            cyclic leftshift by 4
   <     2          print the first two elements

Jakube

Posted 2015-05-18T13:28:26.857

Reputation: 21 462

4beautiful, I'm starting to like Pyth already – Juan Cortés – 2015-05-18T14:12:57.847

3

@JuanCortés: This might be a good resource if you're looking to get started with Pyth.

– Alex A. – 2015-05-18T14:37:19.457

7

Python 3, 123 76 72 62 bytes

I'm a newcomer, gotta start somewhere...

 for l in G:
  d=l.rstrip().split(',');x=[0,4][len(d)>5];print(d[x:x+2])

With xnor's and DLosc's suggestions (62 bytes):

for l in G:d=l.rstrip().split(',');print(d[4*(len(d)>5):][:2])

monguin

Posted 2015-05-18T13:28:26.857

Reputation: 189

8

Welcome to Programming Puzzles and Code Golf! Since this is a [tag:code-golf] competition, you'll want to make your code as short as possible. One thing you could do is decrease the amount of space used for indents; a single space suffices in Python. This post lists tips for golfing in Python and may be a good reference.

– Alex A. – 2015-05-18T14:28:02.650

@Alex, thanks - I was trying to figure out what the exact rules are, I was hoping I could ignore some whitespace, but I guess not. – monguin – 2015-05-18T14:31:54.397

Nope, newlines and spaces both factor into your character count. – Alex A. – 2015-05-18T14:32:39.233

In fact, in this case, you don't even need the newline and indent. Block statements like for can be all on the same line in Python, as long as there isn't another block statement in the body. – DLosc – 2015-05-18T19:32:53.710

3

A good start. You can put everything on the same line as the for to avoid indents. The conditional [0,4][...] can be shortened to 4*(...), using the fact that bools equal 0/1. Also, if you write d[x:x+2] as d[x:][:2], though one character longer, lets you avoid saving the expression for x to a variable.

– xnor – 2015-05-18T21:48:11.363

@xnor Thanks, is there an etiquette for making updates based on others' suggestions? – monguin – 2015-05-19T14:56:55.587

@monguin Usually people just update the code, and sometimes say "thanks to [username] for golfing help" or whatever – undergroundmonorail – 2015-05-19T20:36:25.377

7

Perl, 24

perl -pe's/(\d+,){4}|,\d+,\d+$//'

Example:

perl -pe's/(\d+,){4}|,\d+,\d+$//' <in
103,2
106,1
67,2
4,20

nutki

Posted 2015-05-18T13:28:26.857

Reputation: 3 634

1

This would be 20 bytes in Retina. ;)

– Martin Ender – 2015-05-18T14:49:09.780

4

Sed, 32 bytes

s/,/=/4
s/.*=//
s/,/:/2
s/:.*//

This deletes everything up to the 4th comma if there is one. Then it deletes everything from the 2nd comma (which may have previously been 6th).

And I even managed to right-justify!

Toby Speight

Posted 2015-05-18T13:28:26.857

Reputation: 5 058

Any chance of seeing a demo? – Juan Cortés – 2015-05-18T16:39:42.203

I'm not sure what you want from a demo - I ran your supplied test input and got the required output. – Toby Speight – 2015-05-18T17:09:58.893

4

Javascript, 44 bytes

Assuming input in variable G.

Edit: I just realized, this looks a lot like nutki's perl solution.

alert(G.replace(/(\d+,){4}|,\d+,\d+$/gm,''))

Snippet Demo:

function run(){
    G = input.value;
    /* start solution */
    alert(G.replace(/(\d+,){4}|,\d+,\d+$/gm,''))
    /* end solution */
}
<textarea id="input" cols="25" rows="6">103,2,50,100
106,1,900,900
459,40,150,300,67,2
4,20,30,6000</textarea><br />
<button id="run" onclick="run();">Run</button>

nderscore

Posted 2015-05-18T13:28:26.857

Reputation: 4 912

4

Scala, 68 bytes

G.map(_.split(",")).map(x=>println((x++x).slice(4,6).mkString(",")))

-- MrBones

Scala, 46 70 bytes

Edit: Print out the result

for{l<-G;r=l.split(",");x=(r++r).slice(4,6).mkString(",")}{println(x)}

Demo

Gabriel Jones

Posted 2015-05-18T13:28:26.857

Reputation: 141

11 byte less, by using map instead G.map{k=>val x=k.split(",");println((x++x).slice(4,6).mkString(","))} – Squidly – 2015-05-19T11:29:53.520

1another byte saved by dropping the binding: G.map(_.split(",")).map(x=>println((x++x).slice(4,6).mkString(","))) – Squidly – 2015-05-19T11:32:15.320

3

CJam, 18 15 14 bytes

r{',/4m<2<pr}h

Try it online in the CJam interpreter.

How it works

r      e# Read a whitespace separated token from STDIN.
{      e# Do-while loop:
  ',/  e#    Split at commas.
  4m<  e#    Rotate the resulting array 4 units to the left.
  2<   e#    Discard everything but the first 2 elements.
  p    e#    Print the array.
  r    e#    Read a whitespace separated token from STDIN.
}h     e# If the token is a nonempty string, repeat the loop.

Dennis

Posted 2015-05-18T13:28:26.857

Reputation: 196 637

3

Javascript, 117 112 99 95 84 76 71 bytes

for(r of G.split('\n'))s=r.split(','),console.log(s[t=s[4]?4:0],s[t+1])

JS Fiddle

RichieAHB

Posted 2015-05-18T13:28:26.857

Reputation: 161

1Please post a fiddle, or demo – Juan Cortés – 2015-05-18T14:20:01.550

You can remove two b by replacing ; with , in the loop body and therefore removing the braces { and } – Juan Cortés – 2015-05-18T14:46:48.067

@JuanCortés - thanks, didn't know that. What's the theory behind that? – RichieAHB – 2015-05-18T14:52:26.330

If no braces are added the body of the loop will be the first expression after the closing parenthesis. An expression ends with a semicolon. Separating expressions with commas makes them sort of like an expression group if you may, ending the expression after them – Juan Cortés – 2015-05-18T14:54:34.113

@JuanCortés - makes sense, thanks! – RichieAHB – 2015-05-18T14:56:19.010

1Using for of you can save 3 bytes. It works in any modern browser. for(r of q=G.split('\n'))s=r.split(','),console.log(s[t=s[4]?4:0],s[t+1]) – edc65 – 2015-05-18T15:37:16.717

@edc65 codegolf is happy to eschew IE then ... nice. – RichieAHB – 2015-05-18T15:46:21.837

From what I see in Chrome and Firefox, the q= part is not necessary: for(r of G.split... works. – DocMax – 2015-05-18T19:26:52.260

@DocMax - thanks, forgot to remove that when changing it to for..of – RichieAHB – 2015-05-18T19:30:27.737

3

POSIX shell, 30 bytes

Assuming POSIX sed and cut are present:

sed 's/.*/&,&/'|cut -d, -f5,6

Duplicates the line, leaving the data of interest ready to be extracted from fields 5 and 6.

Toby Speight

Posted 2015-05-18T13:28:26.857

Reputation: 5 058

2

Pip, 12 + 1 = 13 bytes

Uses the -l flag, which gives the output as space-separated lists of numbers on each line.*

_@[4 5]Mg^',

Explanation:

  • The list of numbers is expected in g. Since g is normally initialized from the command-line arguments, you can also put the input there for the same results.
  • ^', splits (each string in) the list on commas.
  • M maps a function to each element in the result.
  • _@[4 5] defines a lambda function. The argument to the function is represented by _; @[4 5] returns a list of its 4th and 5th elements. If the list has six elements, these will be the last two. If it has four, the indices wrap around, and so the result is the first two. (E.g. "abcd"@4 == "abcd"@0 == "a".)
  • We now have a list of lists, like [[103 2] [106 1] [67 2]], which is auto-printed at the end of the program. The -l flag joins each sub-list on space and then the whole thing on newline, so the result is as follows:
C:\>pip.py -le "_@[4 5]Mg^'," 103,2,50,100 106,1,900,900 459,40,150,300,67,2
103 2
106 1
67 2

* Currently. I may change this behavior, but I'm still planning to have some flag that does the same thing.

DLosc

Posted 2015-05-18T13:28:26.857

Reputation: 21 213

1

Perl, 37

@c=/(\d+,\d+)/g;$_=@c>2?$c[2]:$c[0]

35 characters +2 for -p and -l. I'm not sure if there is an approach in Perl that would beat @nutki's solution, but I figured I'd post this idea I had anyway.

Run with:

cat input.txt | perl -ple'@c=/(\d+,\d+)/g;$_=@c>2?$c[2]:$c[0]'

hmatt1

Posted 2015-05-18T13:28:26.857

Reputation: 3 356

1

bash, 54

while IFS=, read {a..f};do echo ${e:-$a},${f:-$b};done

izabera

Posted 2015-05-18T13:28:26.857

Reputation: 879

0

C, 95 bytes

f(a,b,c,d){scanf("%d,%d,%*d,%*d,%d,%d",&a,&b,&c,&d)>2?printf("%d,%d",c,d):printf("%d,%d",a,b);}

The code is simple. Here is the ungolfed version:

f(a,b,c,d){                                    //Four int variables
    scanf("%d,%d,%*d,%*d,%d,%d",&a,&b,&c,&d)>2 //Scan input
        ?                                      //If scanf returned a value > 2
        printf("%d,%d",c,d)                    //Print last two values
        :                                      //else 
        printf("%d,%d",a,b);                   //Print first two values
}

Test it here

Spikatrix

Posted 2015-05-18T13:28:26.857

Reputation: 1 663

0

Ruby, 53

G.each_line{|x|g=x.split',';p[g[4]||g[0],g[5]||g[1]]}

or is good.

MegaTom

Posted 2015-05-18T13:28:26.857

Reputation: 3 787