20
\$\begingroup\$

Code Golf Measurer © 2019

Hexdumps used with xxd look something like this:

00000000: 666f 6f20 6261 7220 7370 616d 2065 6767  foo bar spam egg
00000010: 730a                                     s.

Your task is to convert a hexdump in this form in to the number of bytes used.

Rules:

  • Usual loopholes forbidden.
  • This is , so shortest valid answer in bytes wins.
  • You may or may not include the newline at the end of text (0a). This means that if the hexdump ends in a newline (0a), that input may have it's output reduced by one.
  • An empty input (literally nothing: empty list/string/etc.) must output 0.
  • Input can be taken in any form
  • Input will be valid ASCII with no control characters
  • The input must contain the whole hexdump

Test cases:

00000000: 4865 6c6c 6f2c 2077 6f72 6c64 2120 4865  Hello, world! He
00000010: 6c6c 6f2c 2077 6f72 6c64 210a            llo, world!.

returns 28 or 27

00000000: 0a                                       .

returns 1 or 0

00000000: 6368 616c 6c65 6e67 650a                 challenge.

returns 10 or 9

00000000: 4865 6c6c 6f2c 2077 6f72 6c64 21         Hello, world!

returns 13


returns 0 (This is literally nothing: empty list/string/etc.)

Explanations would be nice for non-standard languages.

\$\endgroup\$
  • \$\begingroup\$ May we assume the input is ascii? Can it contain control characters? What are the input rules? Some languages can't handle input over multiple lines. Can we pad the last line so that all lines are equally long? Why include the blank input? \$\endgroup\$ – Stewie Griffin Oct 7 at 17:03
  • \$\begingroup\$ @StewieGriffin Yes; no; yes; because if xxd is fed an empty string, it outputs nothing. \$\endgroup\$ – gadzooks02 Oct 7 at 17:05
  • 1
    \$\begingroup\$ @StewieGriffin You edited your comment while I was answering, so here's an expansion: Yes; No; it can be input however you want, provided the whole dump is included; See last answer; Yes; Because if xxd is fed an empty string, it outputs nothing \$\endgroup\$ – gadzooks02 Oct 7 at 17:24
  • 1
    \$\begingroup\$ @JonathanAllan Oh yes, well spotted. \$\endgroup\$ – gadzooks02 Oct 7 at 17:41
  • 1
    \$\begingroup\$ Counting a hexdump format that didn't include the ASCIIfied data at the right might be interesting. Everyone's going with just stripping the hex part and byte-counting the rest. If the challenge was to do this given only the last line of hexdump, that would force parsing the hex number (the position) as well as counting the number of hex digits on that line. (Like I do by hand when looking at objdump disassembly or nasm listings for machine-code answers.) I guess I should post that in the sandbox... \$\endgroup\$ – Peter Cordes Oct 8 at 18:29

20 Answers 20

12
\$\begingroup\$

Retina 0.8.2, 8 bytes

.{51}

.

Try it online! Explanation:

.{51}

Delete the first 51 characters of each line. (Lines can only have between 52 and 67 characters, so this always matches once per line.)

.

Count the remaining non-newline characters.

7 bytes if empty input did not have to be supported:

.{52}


Try it online! Explanation:

.{52}

Delete the first 52 characters of each line. (Lines can only have between 52 and 67 characters, so this always matches once per line.)


Count 1 more than the number of remaining characters (including newlines).

\$\endgroup\$
  • \$\begingroup\$ 7 with &`.{52}. \$\endgroup\$ – Grimmy Oct 8 at 14:35
  • \$\begingroup\$ @Grimy That's just... awesome... you must post that as your own answer. \$\endgroup\$ – Neil Oct 8 at 14:40
  • \$\begingroup\$ I didn't notice it at first but actually there's already an almost identical answer. \$\endgroup\$ – Grimmy Oct 8 at 14:54
11
\$\begingroup\$

tcsh, 12 bytes

xxd -r|wc -c

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Very robust and do exactly what OP want. \$\endgroup\$ – tsh Oct 10 at 6:44
7
\$\begingroup\$

V (vim), 7 bytes

Î51x
Ø.

Try it online!

Explanation:

Î       " On every line...
 51x    "   Delete the first 51 characters
Ø.      " Count the number of remaining characters on any line

Hexdump:

00000000: ce35 3178 0dd8 2e                        .51x...
\$\endgroup\$
6
\$\begingroup\$

Retina, 7 bytes

This counts the total number of single-line strings of length 52. It might be possible to do something similar to %52,`., but I failed to find a way to fix that.

w`.{52}

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Also: &`.{52} for Retina 0.8.2. \$\endgroup\$ – Grimmy Oct 8 at 14:56
5
\$\begingroup\$

APL (Dyalog Extended), 18 bytes

Full program. Prompts for list of strings (i.e. of lists of characters).

2÷⍨≢∊(1↓≠⊆⊢)¨49↑¨⎕

Try it online!

 prompt

49↑¨ take the first 49 characters from each

( apply the following tacit function to each:

 the argument

 chop into runs of characters that are

 different from the padding character (space)

1↓ drop the first "word"

ϵnlist (flatten)

 tally

2÷⍨ divide by two

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

Jelly, 5 bytes

Ẉ_51S

A monadic Link accepting a list of lines which yield the integer byte count.

Try it online!

How?

Ẉ_51S - Link: list of lists of characters, H
Ẉ     - length of each (line in H)
  51  - literal fifty-one
 _    - subtract (vectorises)
    S - sum
\$\endgroup\$
  • \$\begingroup\$ You can accept a list of lines. Also, would you care to add an explanation? \$\endgroup\$ – gadzooks02 Oct 7 at 17:20
  • \$\begingroup\$ Ah cool, so is the empty input an empty list OR a list with a single empty line? (This should be made clear in the post since it's an edge-case.) \$\endgroup\$ – Jonathan Allan Oct 7 at 17:26
  • \$\begingroup\$ It's and empty list/string/etc. I've just clarified this. \$\endgroup\$ – gadzooks02 Oct 7 at 17:31
  • \$\begingroup\$ Thanks, explanation added now too. \$\endgroup\$ – Jonathan Allan Oct 7 at 17:34
3
\$\begingroup\$

C (gcc), 64 55 bytes

r;s[];f(l){while(*s=0,gets(s),l=strlen(s))r+=l-51;l=r;}

Try it online!

9 bytes shaved off thanks to YSC!

Here is a more fragile version inspired by Arnauld's JavaScript solution which probably fails for long inputs:

C (gcc), 50 bytes

s[];f(l){l=read(0,s,1<<31);l=l?l/68*16+l%68-51:0;}

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ 59 bytes by changing return r to l=r \$\endgroup\$ – girobuz Oct 8 at 3:40
  • 2
    \$\begingroup\$ @JonathanFrech undefined behaviour is perfectly fine for code golf! \$\endgroup\$ – G. Sliepen Oct 8 at 15:53
  • 1
    \$\begingroup\$ @YSC Hm, but I think making r global violates the rule that if you define a function to do something (and it's not main), it should be possible to call it multiple times. \$\endgroup\$ – G. Sliepen Oct 8 at 15:54
  • 1
    \$\begingroup\$ Anyway, r;s[];f(l){while(*s=0,gets(s),l=strlen(s))r+=l-51;l=r;}: 55 bytes :) \$\endgroup\$ – YSC Oct 8 at 16:04
  • 2
    \$\begingroup\$ @girobuz while() has the same number of bytes as for(;;). Thus ;while() is one byte longer than for(;;). \$\endgroup\$ – Jonathan Frech Oct 8 at 21:25
3
\$\begingroup\$

Python 3, 48 46 bytes

lambda s:(len(s)or 51)+1-52*len(s.split('\n'))

Input is passed as a string to the function. The function increments the length of the input (including newlines), then subtracts 52 for each line.

Try it online

\$\endgroup\$
  • 2
    \$\begingroup\$ From what I've seen, the f= can be moved in to the header as `f=`, leaving just the lambda as code and saving two bytes: Try it online! \$\endgroup\$ – gadzooks02 Oct 8 at 16:03
  • \$\begingroup\$ @gadzooks02 Thanks, will edit. The f= is a habit I picked up from the Python discord server. \$\endgroup\$ – IFcoltransG Oct 9 at 1:39
2
\$\begingroup\$

Japt -x, 5 bytes

Input as an array of lines.

®Ê-51

Try it

®Ê-51     :Implicit input of array
®         :Map
 Ê        :  Length
  -51     :  Subtract 51
          :Implicit output of sum of resulting array
\$\endgroup\$
2
\$\begingroup\$

Perl 6, 18 bytes

{.join.comb-51*$_}

Try it online!

Anonymous Whatever lambda that takes a list of lines and returns the sum of the number of characters, subtracting 51 for each line

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

05AB1E, 8 6 bytes

€g51-O

Try it online!

Input as a list of strings.

€g     get lengths of each line
51-    subtract 51 from each
O      push the sum of the resulting list
       implicitly print
\$\endgroup\$
  • 1
    \$\begingroup\$ Sorry, the input must contain the whole hexdump. (Yours skips the letters at the end of each line) \$\endgroup\$ – gadzooks02 Oct 7 at 17:27
  • \$\begingroup\$ Oh, my bad. I made this on my smartphone. Didn't see there's something behind the hex codes. I made a correction. \$\endgroup\$ – Dorian Oct 7 at 18:02
2
\$\begingroup\$

MathGolf, 7 6 bytes (non-competing)

m£Ex-Σ

It's non-competing (for now) because there is currently a bug in MathGolf for string-inputs containing spaces. They are automatically transformed to a list (split by spaces). In the TIO I've replaced all spaces with a B to show it does work as intended.

Input as a list of strings.

-1 byte by finding a method to generate 51 in 2 bytes (see history for 10+ ways of doing it in 3 bytes..)

Try it online.

Explanation:

m    # Map each string in the (implicit) input-list
 £   #  Pop the string and get the length
E    # Push 15
 x   # Reverse, but keep it an integer
     # (NOTE: simply `51` would be interpret as two values on the stack: 5 and 1)
  -  # Subtract each of the lengths by this
Σ    # Take the sum of the list
     # (after which the entire stack joined together is output implicitly as result)
\$\endgroup\$
2
\$\begingroup\$

IBM/Lotus Notes Formula Language, 53 bytes

@Sum(@Length(@Explode(@Right(@Left(i;"  ");": ")))/2)

There is no TIO for Formula so here are screenshots of the test cases:

enter image description here enter image description here enter image description here enter image description here enter image description here

The formula is in the computed field that provides the value after "Returns".

Explanation

This is a good demonstration of the way that Formula will recursively apply a function to a list without needing a loop. The formula is in a computed field on the same form as editable input field `i'.

  1. Start in the middle. @Left and @Right allow a string delimiter or a number of characters to be used. We therefore search to the right of : and then to the left of the first occurrence of two spaces. Since Formula sees the newline as a list separator it will apply this to each line in the input.
  2. @Explode is Formula's equivalent of a split function and defaults to space, , or ;. Again it is applied to each line in the field but this time the results are combined into a single list.
  3. @Length will then be applied to each member of the list. In each case we divide it's return value by 2.
  4. @Sum the whole list and output the result.
\$\endgroup\$
  • 1
    \$\begingroup\$ Do you have a link to an interpreter (either online or downloaded)? \$\endgroup\$ – gadzooks02 Oct 8 at 16:05
  • \$\begingroup\$ Unfortunately not. Formula is a proprietary language that is tied in to the IBM product (I did ask on Meta some time ago if this is allowed on this site and the answer was "yes" but not for Cops & Robbers challenges). Last time I looked, Domino Designer (which supports Formula) was still available as a free download from IBM. Unfortunately Windows only and as I run Linux at home I can't confirm. This answer was written during my lunch break as I am unfortunate enough to still support some legacy Notes apps and still have Notes on my machine at work :-) \$\endgroup\$ – ElPedro Oct 8 at 18:15
  • 1
    \$\begingroup\$ BTW, if you search Lotus Notes on this site you will find that I am the only guy who is stupid enough to try to golf in this language :-) \$\endgroup\$ – ElPedro Oct 8 at 19:34
1
\$\begingroup\$

JavaScript (ES6), 34 bytes

s=>(n=s.length)&&(n/68<<4)+n%68-51

Try it online!

Commented

s =>                // s = input string
  (n = s.length) && // n = length of s; return 0 right away if n = 0 (special case)
  (n / 68 << 4) +   // otherwise compute the number of full lines and multiply it by 16
  n % 68 - 51       // add the length of the last line minus 51
\$\endgroup\$
1
\$\begingroup\$

Red, 81 55 bytes

func[s][n: 0 foreach l s[n: n - 51 + length? l]max 0 n]

Try it online!

Takes the input as a list of strings.

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

JavaScript, 33 32 bytes

a=>a.map(x=>a=~~a+x.length-51)|a

Try it Online!

Saved 1 byte thanks to Arnauld.

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

Befunge-98 (FBBI), 16 bytes

"c- cw|r- dxx"=@

Try it online!

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

Stax, 5 bytes

ôφß→ê

Run and debug it

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

Zsh, 36 bytes

With zsh's default flags:

for l (${(f)1})((c+=$#l-52))
<<<$[c]

Try it online!

${(f)1} splits $1 on newlines, and discards empty lines. The $[ arithmetic expansion ] guards against the empty case, when the loop never sets $c.

Zsh, 28 bytes

With -o extendedglob:

<<<${#${(F)${(f)1}#?(#c52)}}

Try it online!

(f) Split on newlines, ${ #?(#c52)} remove leading 52 characters, (F) join on newlines so that counting is characterwise instead of listwise, ${# } count characters.

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

asm2bf, 135 bytes

Golfed version:

lbl 3
mov r2,51
lbl 1
in_ r1
dec r2
jz_ r1,4
jnz r2,1
lbl 2
in_ r1
jz_ r1,4
sub r1,10
jz_ r1,3
inc r3
jmp 2
lbl 4
out r3

Commented version:

lbl 3               ; Main loop - the kinda entry point

    mov r2, 51      ; Loop 51 times.
    lbl 1           ; Loop start.
        in_ r1      ; Read character
        dec r2      ; Decrement the loop accumulator.
        jz_ r1, 4   ; If zero was read, end.
        jnz r2, 1   ; If we still loop, loop again.

    lbl 2           ; Second loop, accumulating the result.
        in_ r1      ; Read a character.
        jz_ r1, 4   ; If character is zero, end the loop and print result.
        sub r1, 10  ; Decrement r1 by 10 for next check.
        jz_ r1, 3   ; If the character - 10 (the newline) is zero, jump to 3
        inc r3      ; Increment character read amount.
        jmp 2
lbl 4
    out r3          ; Print out the result as an ASCII character.
\$\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.