Hexadecimal and the Alphabet

45

4

In this challenge, you will receive an input, convert it to hexadecimal, make a couple changes, and output the result.

Because they are only 16 characters in hexadecimal, your code will need to be as short as possible.


Examples

Examples are separated by a blank line. First line is input, second line shows the steps, third shows the output

234589
234589 -> 3945D -> 39454 -> 9A1E -> 9115 -> 239B -> 2392 -> 958
958

435234
435234 -> 6A422 -> 61422 -> EFEE -> 5655 -> 1617
1617

153
153 -> 99 -> 99 -> 63
1617

Steps

The input will always be a positive integer


In order to generate the output you will follow the following steps:

  1. Convert the input to hexadecimal
  2. Replace any letters with their index in the alphabet (e.g. a -> 1, b -> 2)
  3. Convert the result back to hexadecimal
  4. If the result contains any letters, go to step 2. If not, output the result

This is so shortest code in bytes wins!

Downgoat

Posted 2015-12-19T18:21:57.570

Reputation: 27 116

27+1 for the justification "Because they are only 16 characters in hexadecimal, your code will need to be as short as possible." – cat – 2015-12-19T18:29:33.663

1A test case that passes through a zero digit (which is an important edge case for my current approach): 749699 -> B7083 -> 27083 -> 69CB -> 6932 -> 1B14 -> 1214 -> 4BE -> 425 -> 1A9 -> 119 -> 77 – Martin Ender – 2015-12-19T18:53:16.757

5Test case 153. Step 1 > 99, Step 2 --> 99, Step 3 --> 63, output 63. Correct? – edc65 – 2015-12-21T12:09:24.477

Yes for 153 I had not seen the code Flow explanation... – RosLuP – 2019-01-30T09:51:21.057

For what it's worth... 3 out of the top 4 answers return 99 on input 153 and Dennis's seg-faults on the current version of Jelly. I'm going to quit testing while I'm ahead :) Are we sure that example is correct? – dana – 2019-01-31T04:31:41.803

Answers

13

Jelly, 18 bytes

b⁴µ:⁵©+¹%⁵ḅ⁵ß¹®S¤?

Try it online!

The binary, 18 byte version of the source code has the xxd dump

0000000: 62 b6 8c 3a b7 85 2b 8e 25 b7 a3 b7 95 8e 88 53 83 3f b..:..+.%......S.?

and works with this version of the Jelly interpreter.

How it works

b⁴µ:⁵©+¹%⁵ḅ⁵ß¹®S¤?  Define the main link -- Left input: a (number)

b⁴                  Convert from integer to base 16.
  µ                 Start a new, monadic link.
   :⁵               Divide all base 16 digits by 10.
     ©              Save the result in a register.
      +¹            Add the quotients to the base 16 digits.
        %⁵          Take all resulting sums modulo 10.
          ḅ⁵        Convert from base 10 to integer.
              ®S¤   Take the sum of the quotients from the list in the register.
                 ?  If the result is non-zero:
            ß         Recursively call the main link.
             ¹        Else, apply the identity function.

(decimal-to-integer) should have worked as a shorthand for ḅ⁵, but the latest version of Jelly at the time of this post had a bug that prevented me from using it.

Dennis

Posted 2015-12-19T18:21:57.570

Reputation: 196 637

3What....is.....that....? – J Atkin – 2015-12-19T18:52:35.010

1Which encoding does this use? It doesn't look like UTF-8, or ISO-8859 – Downgoat – 2015-12-19T18:56:49.270

2@Downgoat It isn't. Jelly uses its own, custom encoding. The source code can be provided either in UTF-8 or as a binary file. – Dennis – 2015-12-19T18:57:35.257

@Dennis: Please provide documentation of that encoding, and preferably, the language too. Perhaps write an esolangs wiki article on it? That will increase its visibility too :) – Timwi – 2015-12-19T19:20:11.967

@Timwi Documentation is work in progress. I haven't documented the encoding yet, since it is still changing with every commit. The same goes for pretty much all other features... – Dennis – 2015-12-19T19:22:11.660

@Timwi It's in this file: code = ''.join([char_table[i] for i in code])

– Dennis – 2015-12-19T19:25:35.587

@Dennis: Yes, found it now. I think you’re making it too easy for yourself. You just put a line in your parser so that it can theoretically read a binary format in which each character is one byte, but you didn’t actually write your program in it. You wrote it in a Unicode-enabled editor using Unicode characters. You did not post the binary file that is actually 18 bytes, and even if you did, it will become invalid with every new instruction you add to the language. – Timwi – 2015-12-19T19:29:27.980

@Timwi Re scoring, how is that different from every single APL answer on this site? Nobody actually uses the APL code page... The source code in the custom encoding is 0000000: 62 b6 8c 3a b7 85 2b 8e 25 b7 a3 b7 95 8e 88 53 83 3f b..:..+.%......S.? (xxd dump). It is only changing since the language is currently under development. The char table will be fixed later. – Dennis – 2015-12-19T19:32:01.453

@Dennis: APL has a fixed, published, known encoding. I didn’t say you can’t score one character per byte; I just think you should post the answer that is actually 18 bytes in order to claim 18 bytes, and if you want to change the encoding in your interpreter, then your answer should state which old version of the interpreter understands the encoding you used in the answer. – Timwi – 2015-12-19T19:38:10.560

2@Timwi Fair enough. I've added both to the post. – Dennis – 2015-12-19T19:44:05.240

2In the defense of Dennis: since Jelly uses less than 256 chars, one could trivially define a fork of Jelly that just uses ANSI chars. The only difference would be readability and ease of remembering what each function does. – Adám – 2015-12-20T12:58:23.343

Actual link make jelly interpreter to segfault... There would be in the text what jelly version and the link point to that version...or not use a link – RosLuP – 2019-01-30T09:38:48.577

8

JavaScript ES6, 98 92 67 64 bytes

Saved 3 bytes thanks to @Downgoat, 3 more thanks to @user81655

Found a much, much shorter version, ditching the loop for recursion:

h=x=>(y=x.toString(16))>(r=y.replace(/\D/g,z=>'0x'+z-9))?h(+r):r

Probably the most interesting part of this program is the replace function:

z=>     // Implicit: z = one of "a", "b", "c", "d", "e", "f"
'0x'+z  // Add '0x' to the beginning of z.
        // If z == "a", this results in "0xa".
-9      // Subtract 9. JavaScript automatically coerces the string to a number,
        // and because the prefix "0x" means "convert from hexadecimal",
        // the "a" is converted to 10, which then becomes 1 because of the subtraction.

Test snippet

(taken from here)

h=x=>(y=x.toString(16))>(r=y.replace(/\D/g,z=>'0x'+z-9))?h(+r):r
<!--                               Try the test suite below!                              --><strong id="bytecount" style="display:inline; font-size:32px; font-family:Helvetica"></strong><strong id="bytediff" style="display:inline; margin-left:10px; font-size:32px; font-family:Helvetica; color:lightgray"></strong><br><br><pre style="margin:0">Code:</pre><textarea id="textbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><pre style="margin:0">Input:</pre><textarea id="inputbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><button id="testbtn">Test!</button><button id="resetbtn">Reset</button><br><p><strong id="origheader" style="font-family:Helvetica; display:none">Original Code Output:</strong><p><div id="origoutput" style="margin-left:15px"></div><p><strong id="newheader" style="font-family:Helvetica; display:none">New Code Output:</strong><p><div id="newoutput" style="margin-left:15px"></div><script type="text/javascript" id="golfsnippet">var bytecount=document.getElementById("bytecount");var bytediff=document.getElementById("bytediff");var textbox=document.getElementById("textbox");var inputbox=document.getElementById("inputbox");var testbtn=document.getElementById("testbtn");var resetbtn=document.getElementById("resetbtn");var origheader=document.getElementById("origheader");var newheader=document.getElementById("newheader");var origoutput=document.getElementById("origoutput");var newoutput=document.getElementById("newoutput");inputbox.value="234589";textbox.style.width=inputbox.style.width=window.innerWidth-50+"px";var _originalCode=null;function getOriginalCode(){if(_originalCode!=null)return _originalCode;var allScripts=document.getElementsByTagName("script");for(var i=0;i<allScripts.length;i++){var script=allScripts[i];if(script.id!="golfsnippet"){originalCode=script.textContent.trim();return originalCode}}}function getNewCode(){return textbox.value.trim()}function getInput(){try{var inputText=inputbox.value.trim();var input=eval("["+inputText+"]");return input}catch(e){return null}}function setTextbox(s){textbox.value=s;onTextboxChange()}function setOutput(output,s){output.innerHTML=s}function addOutput(output,data){output.innerHTML+='<pre style="background-color:'+(data.type=="err"?"lightcoral":"lightgray")+'">'+escape(data.content)+"</pre>"}function getByteCount(s){return(new Blob([s],{encoding:"UTF-8",type:"text/plain;charset=UTF-8"})).size}function onTextboxChange(){var newLength=getByteCount(getNewCode());var oldLength=getByteCount(getOriginalCode());bytecount.innerHTML=newLength+" bytes";var diff=newLength-oldLength;if(diff>0){bytediff.innerHTML="(+"+diff+")";bytediff.style.color="lightcoral"}else if(diff<0){bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgreen"}else{bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgray"}}function onTestBtn(evt){origheader.style.display="inline";newheader.style.display="inline";setOutput(newoutput,"");setOutput(origoutput,"");var input=getInput();if(input===null){addOutput(origoutput,{type:"err",content:"Input is malformed. Using no input."});addOutput(newoutput,{type:"err",content:"Input is malformed. Using no input."});input=[]}doInterpret(getNewCode(),input,function(data){addOutput(newoutput,data)});doInterpret(getOriginalCode(),input,function(data){addOutput(origoutput,data)});evt.stopPropagation();return false}function onResetBtn(evt){setTextbox(getOriginalCode());origheader.style.display="none";newheader.style.display="none";setOutput(origoutput,"");setOutput(newoutput,"")}function escape(s){return s.toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}window.alert=function(){};window.prompt=function(){};function doInterpret(code,input,cb){var workerCode=interpret.toString()+";function stdout(s){ self.postMessage( {'type': 'out', 'content': s} ); }"+" function stderr(s){ self.postMessage( {'type': 'err', 'content': s} ); }"+" function kill(){ self.close(); }"+" self.addEventListener('message', function(msg){ interpret(msg.data.code, msg.data.input); });";var interpreter=new Worker(URL.createObjectURL(new Blob([workerCode])));interpreter.addEventListener("message",function(msg){cb(msg.data)});interpreter.postMessage({"code":code,"input":input});setTimeout(function(){interpreter.terminate()},1E4)}setTimeout(function(){getOriginalCode();textbox.addEventListener("input",onTextboxChange);testbtn.addEventListener("click",onTestBtn);resetbtn.addEventListener("click",onResetBtn);setTextbox(getOriginalCode())},100);function interpret(code,input){window={};alert=function(s){stdout(s)};window.alert=alert;console.log=alert;prompt=function(s){if(input.length<1)stderr("not enough input");else{var nextInput=input[0];input=input.slice(1);return nextInput.toString()}};window.prompt=prompt;(function(){try{var evalResult=eval(code);if(typeof evalResult=="function"){var callResult=evalResult.apply(this,input);if(typeof callResult!="undefined")stdout(callResult)}}catch(e){stderr(e.message)}})()};</script>

ETHproductions

Posted 2015-12-19T18:21:57.570

Reputation: 47 880

It'll save a few bytes to use a function for .toString(16): x=>eval("for(x=(j=n=>n.toString(16))(x);/\\D/.test(x);)x=j(+x.replace(/\\D/g,z=>+('0x'+z)-9))"). It might also save a few bytes using recursion – Downgoat – 2015-12-19T20:00:52.473

@Downgoat Thanks! I'd tried a .replace on the string before evaluating it, but that turned out longer. – ETHproductions – 2015-12-19T20:07:40.780

Also remember you can make it an anonymous function, omitting h= – Conor O'Brien – 2015-12-19T22:16:47.163

@CᴏɴᴏʀO'Bʀɪᴇɴ Thanks for the suggestions, but that won't work, because it needs to call itself. – ETHproductions – 2015-12-19T22:33:41.897

Gah! Didn't see the recursion. I'm and idiot >_< – Conor O'Brien – 2015-12-19T22:34:32.847

I realize this is an old answer. It seems to return an in correct answer for input 153. Expected result is 63. My original solution had the same issue. – dana – 2019-01-31T04:22:46.290

6

CJam, 21 19 bytes

r{siGb_{(9%)}%_@#}g

Test it here.

Explanation

A very rare case of negative modulo results being helpful. :)

r       e# Read input.
{       e# While the condition on top of the stack is truthy...
  s     e#   Convert to string. This is a no-op in the first iteration, but necessary
        e#   on subsequent iterations.
  i     e#   Convert to integer.
  Gb    e#   Get base-16 digits.
  _{    e#   Copy and map over the copy...
    (   e#   Decrement.
    9%  e#   Modulo 9. If the digit was originally in the range 0 to 9, it will remain
        e#   unchanged because -1 % 9 == -1. If the digit was in 10 to 15, it will become
        e#   0 to 5, respectively.
    )   e#   Increment. Undoes the decrement for unchanged digits and fixes the letter
        e#   digits because A corresponds to 1, not 0.
  }%
  _     e#   Duplicate result.
  @#    e#   Pull up original digits and try to find them in the array. This will be zero,
        e#   i.e. falsy, if they are equal and -1, i.e. truthy, if they are not.
}g

Martin Ender

Posted 2015-12-19T18:21:57.570

Reputation: 184 808

Looks like another might be failing for 153? It seems odd that 3 out of the top 4 answers would have the same issue? http://cjam.aditsu.net/#code=r%7BsiGb_%7B(9%25)%7D%25_%40%23%7Dg&input=153

– dana – 2019-01-31T04:27:36.497

4

Ruby, 35 + 1 = 36

With command-line flag p, run

$_='%x'%$_
redo if$_.tr!'a-f','1-6'

Explanation:

The -p flag creates a loop, storing the input and eventual output in the variable $_. '%x' does the hex conversion, and tr! does the digit substitution and returns a falsey value if there wasn't anything to change. redo starts over with the new $_.

histocrat

Posted 2015-12-19T18:21:57.570

Reputation: 20 600

4

MATL, 23 25 bytes

Disclaimer

While writing this answer I noticed a bug in MATL's dec2base function, corrected it, and released a new version with the correction (as well as a couple other accumulated, unrelated changes).

Since I am using a version which is later than this challenge, according to consensus on Meta this answer is not eligible for winning.

Code

i`0:15YAt9X\t10ZQbb=~a]

Example

>> matl i`0:15YAt9X\t10ZQbb=~a]
> 234589
958

Explanation

i             % input number
`             % do...while
  0:15YA      % convert number to representation with base defined by symbols 0,...,15
  t9X\        % duplicate vector. Modulus 9 with 0 replaced by 9      
  t10ZQ       % duplicate vector and convert to number using base 10
  bb=~a       % are second- and third-top stack elements different? (If so, next iteration)
]             % end        

Luis Mendo

Posted 2015-12-19T18:21:57.570

Reputation: 87 464

You could write an answer in the old version of the language! – lirtosiast – 2015-12-19T23:43:06.643

@ThomasKwa The problem is that in the old version the compiler has a bug. I corrected it in the new version, which tangentially includes some (unrelated) new features – Luis Mendo – 2015-12-20T03:05:20.223

4

Julia, 78 74 bytes

f(x)=(h=hex(x);isdigit(h)?h:f(parse(replace(h,r"[a-z]",c->Int(c[1])-96))))

This is a recursive function that accepts an integer and returns a string.

Ungolfed:

function f(x::Integer)
    # Get the hexadecimal representation of x as a string
    h = hex(x)

    # Check whether all characters are digits
    if isdigit(h)
        # Return the hexadecimal representation of the input
        h
    else
        # Replace each letter with its position in the alphabet,
        # parse as an integer, and call f on the result
        f(parse(replace(h, r"[a-z]", c -> Int(c[1]) - 96)))
    end
end

Alex A.

Posted 2015-12-19T18:21:57.570

Reputation: 23 761

3

Dyalog APL, 37 36 33 bytes

{∧/9≥X←16⊥⍣¯1⊢⍵:10⊥X⋄∇10(⊣⊥|+≤)X}

Thanks to Adám and ngn for suggestions. I'm keeping 16⊥⍣¯1⊢⍵ instead of ⍵⊤⍨⍴⍨16 - it's an extra byte, but allows us to operate on numbers of arbitrary size rather than 64-bit.

voidhawk

Posted 2015-12-19T18:21:57.570

Reputation: 1 796

-2 by choosing the right inequality functions: {∧/9≥X←16⊥⍣¯1⊢⍵:10⊥X⋄∇10⊥10|X+9<X}

– Adám – 2019-01-29T07:20:27.563

1or even shorter: 10⊥10|X+10≤X -> 10(⊣⊥|+≤)X (technically not equivalent, but works for hex digits) – ngn – 2019-01-29T16:01:02.460

116⊥⍣¯1⊢⍵ -> ⍵⊤⍨⍴⍨16 – ngn – 2019-01-29T16:03:42.803

2

R, 106 103 102 bytes

-3 bytes by using if instead of while

-1 byte thanks to Giuseppe using as.double instead of as.integer

a=function(y){x=as.hexmode(as.double(y))
if(grepl("[a-f]",x)){x=chartr("a-f","1-6",x);return(a(x))};x}

Try it online!

Just add a(your_integer_here) to the TIO to see the result.

> a(234589)
[1] "958"
> a(435234)
[1] "1617"
> a(99999)
[1] "4908"

I used recursion to reapply the function to each successive iteration, on the condition that it doesn't find any of the letters 'abcdef' within the string, when this condition is False, it outputs the result as a string. The best part was my discovery of the chartr function, which allows me to swap elements with corresponding elements in a string. This string comes from the function coercing the hexadecimal into a string format.

Edit: I tried to use sprint("%x",y) instead of as.hexmode(as.double(y)), but I am still required to use as.double somewhere in the code, which was 2 1 byte longer.

Sumner18

Posted 2015-12-19T18:21:57.570

Reputation: 1 334

as.double is shorter than as.integer – Giuseppe – 2018-08-29T23:16:37.673

There are some more golfs to be done but I am on mobile at the moment. Feel free to join our R golfing chat and don't forget to check out (and contribute to) tips for golfing in R!

– Giuseppe – 2018-08-29T23:20:41.220

2

05AB1E, 12 bytes

h[Au₂L‡hÐþQ#

Try it online or verify all test cases.

Explanation:

h              # Convert the (implicit) integer-input to a hexadecimal string
               #  i.e. 234589 → "3945D"
 [             # Start an infinite loop:
  Au           #  Push the uppercase alphabet "ABC...XYZ"
    ₂L         #  Push a list in the range [1,26]
      ‡        #  Transliterate: replace all letters with the integers at the same index
               #   i.e. "3945D" → "39454"
               #   i.e. "239B" → "2392"
       h       #  Convert the integer to a hexadecimal string again
               #   i.e. "39454" → "9A1E"
               #   i.e. "2392" → "958"
        Ð      #  Triplicate it
         þ     #  Leave only the digits of the last copy
               #   i.e. "9A1E" → "91"
               #   i.e. "958" → "958"
          Q    #  Check if these digits and the hexadecimal string are equal
               #   i.e. "9A1E" and "91" → 0 (falsey)
               #   i.e. "958" and "958" → 1 (truthy)
           #   #  And if they are: stop the infinite loop
               # (and output the remaining copy from the triplicate implicitly as result)

ÐþQ could alternatively be D.ï (D: Duplicate; : is_int?) for the same byte-count.

Kevin Cruijssen

Posted 2015-12-19T18:21:57.570

Reputation: 67 575

1@MagicOctopusUrn [hÐþQ#Au₂L‡ doesn't always work unfortunately. The challenge states to convert to hex once first, and then in every iteration. If I paste your code in my test suite, the first three test cases are correct, but the last two fail. – Kevin Cruijssen – 2019-02-01T08:16:01.247

2

C# (Visual C# Interactive Compiler), 92 bytes

n=>{var s=$"{n:x}";for(;(s=$"{s.Aggregate(0,(a,c)=>10*a+c%48):x}").Any(c=>c>57););return s;}

Try it online!

Less golfed code:

// anonymous function with
// input integer n
// output is a string
n=>{
  // 1) Convert the input to hexadecimal
  var s=$"{n:x}";
  for(;
    (s=$"{
      // 2) replace letters with their index in the alphabet
      s.Aggregate(0,(a,c)=>10*a+c%48)
      // 3) Convert the result back to hexadecimal
      :x}"
    // 4) If the result contains any letters, go to step 2
    ).Any(c=>c>57););
  // If not, output the result
  return s;
}

dana

Posted 2015-12-19T18:21:57.570

Reputation: 2 541

Following the algo in the end of question post, 153 has to result in 63 and not 99 as seems to me your function some time ago returned – RosLuP – 2019-01-30T12:56:40.617

1@RosLuP - Got it to work w/ that 153, although now my solution is much longer :) I will work on getting it smaller, but for now at least it is handling that case correctly. – dana – 2019-01-30T16:55:12.453

2

Python, 118 105 bytes

def f(n):h=hex(n)[2:];return h if h.isdigit()else f(int(''.join(map(lambda x:chr((ord(x)-47)%48+47),h))))

basile-henry

Posted 2015-12-19T18:21:57.570

Reputation: 381

2

PHP, 140 126 122 114 112 87 or 84 bytes (including -r)

Not entirely sure about how the rules around this as this is my first codegolf attempt, but the code can be run with php -r without needing <? and ?>

Code

$b=readline();while($c!=$b)$b=preg_replace('/\D/e','ord($0)-96',$c=dechex($b));echo$c

Formatted

$b=readline();
while($c!=$b){
  $b=preg_replace('/\D/e','ord($0)-96',$c=dechex($b));
}
echo "$b\n";

Alternate Code (using argv instead of stdin)

for($b=$argv[1];$c!=$b;)$b=preg_replace('/\D/e','ord($0)-96',$c=dechex($b));echo$b

Formatted

for($b=$argv[1];$c!=$b;) {
  $b=preg_replace('/\D/e','ord($0)-96',$c=dechex($b));
}
echo $b;

Notes

Edit 1: I cut out a call to intval() to save 14 characters as PHP will happily treat numerical strings as numbers.
Edit 2: I removed \n from the output that I forgot to remove after testing, and removed quote marks from the final echo to save a total of 4 characters.
Edit 3: Removed the last call to intval()
Edit 4: Saved 2 bytes by removing quote marks from the regex line
Edit 5: Changed [a-f] to \D to save 3 characters, removed strval call from preg_replace for 8 more; added version that uses argv[] instead of STDIN, moved the loop terminator into the while statement(oops!) saving 11 more characters, and moved the dechex call into the subject part of preg_replace for another 3, making a total of 25; also added a non-stdin version as an alternate version that uses 3 less characters. Thanks for the help, @Blackhole

Jase

Posted 2015-12-19T18:21:57.570

Reputation: 121

Welcome on Code Golf! Since files without opening tags are valid PHP files, we always count the tags in PHP (or alternatively, we count the two bytes for the -r option). But a leading ; is always shorter than a leading ?>, so don't forget it. By the way, here is a shorter code: for($a=$argv[1];$b!=$a;)$a=preg_replace('#\D#e','ord($0)-96',$b=dechex($a));echo$b; (-29 bytes). – Blackhole – 2015-12-19T22:34:32.823

Input 153 should give 63, not 99. But -r is free. (see https://codegolf.meta.stackexchange.com/a/2428/55735)

– Titus – 2019-01-31T11:08:40.993

1

Japt, 21 bytes

ìG
®+zA
eV ?U:ßVmuA ì

Try it online!

A significant improvement over the existing Japt answer. It doesn't handle the 153 -> 63 case proposed in a comment, but none of the other answers seem to either so I'll leave it unless the OP clarifies.

Output as a list of decimal digits, could be changed to outputting a decimal number for 1 byte

Explanation:

ìG               #Get a list of base-16 digits, each as a base-10 number
                    e.g. 234589 -> [3,9,4,5,13]

®+zA             #Increment the numbers greater than 10
                    e.g. [3,9,4,5,13] -> [3,9,4,5,14]

eV ?             #If the second step didn't change any digit:
    U            # Output the digits from step 1
     :           #Otherwise
      ß          # Repeat the program with new input:
       V         #  The result of step 2
        muA      #  With each digit modulo 10
            ì    #  Treated as a base-10 number

Kamil Drakari

Posted 2015-12-19T18:21:57.570

Reputation: 3 461

1

APL(NARS) 104 chars, 208 bytes

f←{k←10⊥{⍵≤9:⍵⋄1+10∣⍵}¨q←{(16⍴⍨⌊1+16⍟⍵)⊤⍵}⍵⋄9≥⌈/q:k,0⋄k,1}
t←{⍵≤0:0⋄0=2⊃v←f⍵:↑f↑v⋄{k←f⍵⋄0=2⊃k:↑k⋄∇↑k}⍵}

test:

  t 153
63
  t 0
0
  t 234589
958
  t 435234
1617
  t ¯123
0

I don't know if it is ok... Possible it is not enough for the standard quality answer...

RosLuP

Posted 2015-12-19T18:21:57.570

Reputation: 3 036

1

Mathematica, 107 bytes

(b=FromDigits)@NestWhile[b[#/.Thread[10~Range~15->Range@6]]~a~16&,#~(a=IntegerDigits)~16,MemberQ[a_/;a>9]]&

Can't think of any more ways to golf this...

LegionMammal978

Posted 2015-12-19T18:21:57.570

Reputation: 15 731

1

Java, 201 bytes

String f(int a){String s=Long.toString(a,16);while(s.matches(".*[a-z].*")){char[]b=s.toCharArray();for(int i=0;i<b.length;i++)if(b[i]>96)b[i]-=48;s=Long.toString(new Long("".valueOf(b)),16);}return s;}

SuperJedi224

Posted 2015-12-19T18:21:57.570

Reputation: 11 342

1

Mathematica, 80 bytes

i=IntegerDigits;f=FromDigits;f[#~i~16//.l_/;Max@l>9:>f[If[#>9,#-9,#]&/@l]~i~16]&

This uses a neat trick for while-loops I learned from alephalpha. The //. is "apply this substitution rule as often as possible". Then we use a pattern, l_/;Max@l>9 which only matches if the hexadecimal digit list still contains digits greater than 9.

Martin Ender

Posted 2015-12-19T18:21:57.570

Reputation: 184 808

1

Japt, 45 40 bytes

Based on my JS answer:

I=_nG -9}H=_=ZsG)f/\D/ ?H$($ÂZr"\\D"I):Z

Pretty pathetic for a golfing language, huh? There seems to be a lot of folks realizing during this challenge that their interpreters have bugs, and I am now included among them. This should be able to be done in 30 bytes or less, but a bug makes this impossible.

This creates a function H that can be called like so:

I=_nG -9}H=_=ZsG)f/\D/ ?H$($ÂZr"\\D"I):Z}
$H(234589)$

Alternatively, here is a full program, taking input from STDIN:

I=_nG -9}H=_=ZsG)f/\D/ ?H$($ÂZr"\\D"I):Z}H$(U

Try it online!

ETHproductions

Posted 2015-12-19T18:21:57.570

Reputation: 47 880

1

GNU Sed (with eval extension), 44

:
y/ABCDEF/123456/
s/^/printf %X /e
/[A-F]/b

I wish sed would allow y/A-F/1-6/. But it doesn't.

Digital Trauma

Posted 2015-12-19T18:21:57.570

Reputation: 64 644

1

Python 3, 101 89 bytes

Overall, this is quite similar to Boomerang's solution, but it takes a few different approaches to various aspects.

def d(n):n=hex(int(n))[2:];return n.isdigit()and n or d(str([ord(c)%12for c in n])[1::3])

This is the expanded version of my original code:

def d(n):
    n = int(n)                        # Interpret input as a decimal integer.
    n = hex(n)[2:]                    # Convert it to hex, stripping the '0x'.
    if n.isdigit():                   # If every character is a digit...
        return n                      # ...we're done.
    else:                             # Otherwise...
        n = ''.join(c if c < ':' else # ...don't change digits (':' is after
                    chr(ord(c - 48))  # '9'), but do change letters ('1' is 48
                    for c in n)       # characters before 'a').
        return d(n)                   # Then follow the process again.

11 bytes were shed thanks to @pacholik (replacing the innards of the join with a single operation that worked for both digits and letters). Another byte was trimmed by replacing the join with a string-slicing trick that hit me in a lightbulb moment (but which already exists in the Python golfing tips, albeit under a heading that specifies Python 2).

Tim Pederick

Posted 2015-12-19T18:21:57.570

Reputation: 1 411

The join can be shortened to str(ord(c)%12)for c in n. – pacholik – 2015-12-20T15:49:05.890

0

Japt, 18 bytes

Æ=ìG ®%9ª9Ãì)sGÃæÑ

Try it

Shaggy

Posted 2015-12-19T18:21:57.570

Reputation: 24 623

0

PHP, 71 bytes

while($n++<2|$b-$a=&$argn)$a=strtr($b=dechex($a),abcdef,123456);echo$a;

Run as pipe with -nR or try it online.

Yields a warning for some inputs in PHP 7.1 and later; replace - with != to fix.
Yields another warning in PHP 7.2; put abcdef in quotes to fix.

Titus

Posted 2015-12-19T18:21:57.570

Reputation: 13 814

0

Seriously, 42 bytes

1╤╝4ª╗,$1WX╛@¿╜@¡;`╜@¿;)╛;(\(+%$`Mεj;)=YWX

Hex Dump:

31d1bc34a6bb2c24315758be40a8bd40ad3b60bd40
a83b29be3b285c282b2524604dee6a3b293d595758

Try it online

There has to be a shorter way than this, but this is what I got... (This is where I find myself wishing W actually popped, since it's shorter to put a ; right before the last one when you DON'T want it to than to put an X after EACH W. Here, having W pop instead of peek would save three bytes.)

quintopia

Posted 2015-12-19T18:21:57.570

Reputation: 3 899