C, int
: 138 123 bytes, long
: 152 131 bytes
I have created two versions of this, as the challenges' limit of a working max input of 0x100000000
seemed a bit odd. One version works with 32 bit integers (which fails the limit for obvious reasons), the other version works with 64 bits (which goes way beyond the given limit, at the cost of 14 8 extra bytes).
32 bit version:
char b[22],*r=b;f(v,l)char*l;{v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}
64 bit version:
char b[22],*r=b;f(long v,char*l){v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(long v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}
This is identical except that it declares the integer variable to be long
(which is 64 bits on linux).
The ungolfed long
version:
char buffer[22],*result=buffer;
f(long value,char*letter){
if(value%3>1){
*result++=*letter,value++;
}
if(value){
f(value/3,letter+1);
}
if(value%3){
*result++=*letter;
}
}
g(long value){
f(value,"139ABCDEFGHIJKLMNOPQR");
*result=0;
result=buffer;
}
As you can see, this works by recursive decent: If the remainder is 1, the respective character is appended to the output string after the recursive call. If the remainder is 2, the output is performed before the recursing. In this case, I also increment the value by one to handle the negative digit correctly. This has the added benefit of changing the remainder to zero, allowing me to use value%3
as the condition for the post-recursion if.
The result of the conversion is placed into the global buffer. The g()
wrapper has the job of zero terminating the resulting string correctly, and to reset the result
pointer to its start (which is also how g()
"returns" the result).
Test the long
version with this code:
#include <stdio.h>
char b[22],*r=b;f(long v,char*l){v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(long v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}
void printConversion(long value) {
g(value);
printf("%ld: %s\n", value, r);
}
int main() {
for(long i = 0; i <= 40; i++) {
printConversion(i);
}
printConversion(0x7fffffff);
printConversion(0xffffffffu);
printConversion(0x100000000);
}
Possible further, but destructive golfing:
-4 bytes: make the function a one-shot by removing the pointer reset in g()
.
-5 bytes: force the caller to perform the string termination, returning the string without termination in buffer
, and the end of the string in result
.
Related – Leaky Nun – 2018-03-28T13:45:24.747
Also related. – Martin Ender – 2018-03-28T13:45:47.637
Balanced ternary is a positional notation. – FrownyFrog – 2018-03-28T13:46:19.970
@FrownyFrog just de-position it and you get roman ternary – Leaky Nun – 2018-03-28T13:46:39.493
2(related doesn't mean duplicate, calm down) – Leaky Nun – 2018-03-28T13:47:02.927
8Am I the only one who has no clue what's being asked here? – Shaggy – 2018-03-28T13:47:25.707
3@Shaggy Express the input as a sum of powers of 3 and their negatives. Put the negatives left of a
|
and the positives to the right of it. – Martin Ender – 2018-03-28T13:48:06.450Do the digits need to be sorted from largest to smallest? – Martin Ender – 2018-03-28T13:50:46.713
1Thanks, @MartinEnder; that explains the 0, 1 & 7 test cases but I still don't see where/how the letters come into play. – Shaggy – 2018-03-28T13:51:05.600
1Maybe some additional information on non-positional base-3 notation would be helpful here – musicman523 – 2018-03-28T13:51:37.540
1@Shaggy 1 is 1, 3 is 3, 9 is 9, A is 27, B is 81, C is 243, ... – Leaky Nun – 2018-03-28T13:51:42.487
@Shaggy They're just used for "digits" which can't be represented by a single decimal digit. A = 27, B = 81, etc. – Martin Ender – 2018-03-28T13:51:49.070
@MartinEnder no, the order is free. – FrownyFrog – 2018-03-28T13:53:57.747
Is the order strict (as in does it matter if we output
CDEF|9AG
,CDEF|GA9
,FEDC|9AG
, orFEDC|GA9
)? If it is, all three current answers are invalid.. – Kevin Cruijssen – 2018-03-28T15:35:09.623You are also allowed to have no separator, in which case the largest digit starts the positive sequence. What? So, if we don't use a separator, the output is to be computed differently so as for the largest digit to be the one which starts the positive sequence? – Erik the Outgolfer – 2018-03-28T15:35:41.650
@EriktheOutgolfer Because the order is not important... – user202729 – 2018-03-28T15:39:10.467
2@KevinCruijssen "no, the order is free." -- OP – user202729 – 2018-03-28T15:39:27.837
3@user202729 Ah, missed that comment. Thanks. That's what happens when rules are in the comments instead of edited into the challenge.. (FrownyFrog, could you add that rule to the challenge: either order on either side of the delimiter is fine?) – Kevin Cruijssen – 2018-03-28T15:51:34.933
@KevinCruijssen Isn't that inferrable from the rules? – user202729 – 2018-03-28T15:55:11.937
1@EriktheOutgolfer If you don't use a separator, the largest digit in the right sequence has to go first. The largest digit in the right sequence is guaranteed to be the largest overall, because the input is positive. – FrownyFrog – 2018-03-28T16:06:31.140
@FrownyFrog Well, it kind of makes the order matter then, but I guess it's not really avoidable, given no separator.. – Erik the Outgolfer – 2018-03-28T16:10:24.490
Is it also OK to have (positive digits, no separator, negative digits) and the largest digit ends the positive sequence? Is space between digits OK? – nwellnhof – 2018-03-28T16:47:43.840
@nwellnhof no, lets keep it vaguely Roman and entirely space-free – FrownyFrog – 2018-03-28T16:50:28.817
FYI instead of posting "X_____________________X" in the sandbox when deleting, just paste in the URL of your main post (I already fixed it). – Magic Octopus Urn – 2018-03-28T17:10:54.983
Clarification please: What is the largest value that we need to be able to convert?
0x7fffffff
(signed 32 bit int),0xffffffff
(unsigned 32 bit int), or0x100000000
(some 64 bit type, most likely)? The last option is what your wording requires currently, but I'm positive that you meant one of the other two possibilities. – cmaster - reinstate monica – 2018-03-29T19:47:15.493@cmaster I wasn’t sure what the options even were, thanks for spelling them out. It’s the second one. – FrownyFrog – 2018-03-30T03:13:39.740
Order matter should go main for some comment folded – l4m2 – 2018-03-31T13:04:39.090
Why did you accept my Java answer? :S It's definitely not the shortest. ;) The 26-bytes Jelly answer is. – Kevin Cruijssen – 2018-05-15T10:04:49.343
@KevinCruijssen 9 edits worth of effort – FrownyFrog – 2018-05-15T10:09:35.297
@FrownyFrog Usually it's best practice to accept the shortest answer in code-golf challenges. I still really appreciate the gesture, though. Thanks. :) – Kevin Cruijssen – 2018-05-15T10:13:46.103