CodeGolf - Ignore the noise #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.

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

• Will input be always of the format x,x,x,x and x,x,x,x,x,x where x denotes a number? – Spikatrix May 18 '15 at 13:40
• Yes, input will follow one of those two formats, let me clarify – Juan Cortés May 18 '15 at 13:40
• Do we need to submit a program or a function or something else? Also, where all can inputs be taken from? – Spikatrix May 18 '15 at 13:42
• 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 May 18 '15 at 14:36
• @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 May 18 '15 at 16:05

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
• beautiful, I'm starting to like Pyth already – Juan Cortés May 18 '15 at 14:12
• @JuanCortés: This might be a good resource if you're looking to get started with Pyth. – Alex A. May 18 '15 at 14:37

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
• This would be 20 bytes in Retina. ;) – Martin Ender May 18 '15 at 14:49

Python 3, 1237672 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])
• Welcome to Programming Puzzles and Code Golf! Since this is a 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. May 18 '15 at 14:28
• @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 May 18 '15 at 14:31
• Nope, newlines and spaces both factor into your character count. – Alex A. May 18 '15 at 14:32
• 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 May 18 '15 at 19:32
• 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 May 18 '15 at 21:48

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!

• Any chance of seeing a demo? – Juan Cortés May 18 '15 at 16:39
• I'm not sure what you want from a demo - I ran your supplied test input and got the required output. – Toby Speight May 18 '15 at 17:09

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>

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

• 1 byte less, by using map instead G.map{k=>val x=k.split(",");println((x++x).slice(4,6).mkString(","))} – Squidly May 19 '15 at 11:29
• another byte saved by dropping the binding: G.map(_.split(",")).map(x=>println((x++x).slice(4,6).mkString(","))) – Squidly May 19 '15 at 11:32

CJam, 1815 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.

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.

Javascript, 11711299958476 71 bytes

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

JS Fiddle

• Please post a fiddle, or demo – Juan Cortés May 18 '15 at 14:20
• You can remove two b by replacing ; with , in the loop body and therefore removing the braces { and } – Juan Cortés May 18 '15 at 14:46
• @JuanCortés - thanks, didn't know that. What's the theory behind that? – RichieAHB May 18 '15 at 14:52
• 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 May 18 '15 at 14:54
• Using 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:0],s[t+1]) – edc65 May 18 '15 at 15:37

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.

Perl, 37

@c=/(\d+,\d+)/g;$_=@c>2?$c:$c 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:$c'

bash, 54

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

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
}

Ruby, 53

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

or is good.