Negate a number

6

You are to accept, on standard input, one number. You will then output the negation of that number. Your code will do nothing else. You may accept various formats if you wish (like "one" or ("uno+2.4e10i"). You may also output it how ever you wish. Note that these formats mush have existed somewhere on the internet before this question. The thing you can't do is use the same 6 character sequence twice in your code. Also, if any set of characters can be removed, and your code still functions the same, they must be removed (no making huge useless strings, since they could just be removed.)

This is code bowling, so the answer with the most characters wins!

Note: In case you were wondering, negation means "multiply by negative one." The representation of the numbers is up to you, but the meaning of negation is not.

PyRulez

Posted 2014-06-13T01:00:30.790

Reputation: 6 547

1Do you mean negation as in 8 -> -8 or negation as in 0100 -> 1011? – Kyle Kanos – 2014-06-13T02:04:45.900

1This SO Q&A suggests that, in general, ~x = -x - 1, which is not the same thing as what you state. You need to clarify this, what exactly do you mean by negation. – Kyle Kanos – 2014-06-13T02:16:22.223

I thought the bit complement was negation. Apparently not. – PyRulez – 2014-06-13T02:28:43.880

2About the "if any set of characters can be removed": does that only apply to consecutive characters or really any set of characters? – Martin Ender – 2014-06-13T07:06:52.137

To build on @m.buettner's question, how are long variable names counted? – Cephalopod – 2014-06-13T10:00:04.937

This is a completely objective criteria if you read the question. – PyRulez – 2014-06-13T15:38:19.277

Objective or not, I don't get it. Either way, it's not a good question. 1. If it refers to any arbitrary set of characters, every GolfScript answer containing a ~, a ) and a ~ after that will have a score of 3, no matter what those characters do (if anything) at the moment. 2. If it refers to consecutive characters, you can still use arbitrarily large strings, as long you check their lengths. – Dennis – 2014-06-14T04:58:49.727

@Dennis There is an upper bound on length. Also, if your golf script works on many different formats, reducing it to~(~ changes it's function, so wouldn't occur. – PyRulez – 2014-06-15T11:59:57.230

@PyRulez: The upper bound is 1592 TB if we restrict ourselves to 1 byte characters. You got me convinced about removing the characters, but this will be extremely difficult to test. Even for a 256 byte program, there are over 10**77 different programs that can be formed just by removing characters. – Dennis – 2014-06-15T14:21:48.510

1I retract my previous comment. This is actually a nice challenge; it's just very difficult to figure out whether a given solution is valid or not. All ideas I had to trivialize it were doomed to failure. – Dennis – 2014-06-16T04:58:14.913

I think as of Dennis's code this has gotten out of hand. There was a question recently where code had to be pointlessly contrived, but ever part had to have some semi-plausible software good practice justification. here it is

– Nathan Cooper – 2014-06-16T14:23:56.760

@NathanCooper This question was sort of an experiment with restricted source and code bowling anyway. They were talking about nuking the tag on meta. – PyRulez – 2014-06-16T14:25:30.853

Answers

7

CJam, 278,548 characters

Stack Exchange has a 30,000 character limit, so I've uploaded my code to Google Drive.

The online interpreter chokes when decoding the lookup tables (Maximum call stack size exceeded), so I suggest using the standard interpreter (requires Java).

I/O

Input should be an integer (in whatever format CJam understands). Output is in British English.

$ cjam negate.cjam <<< 9990001
negative nine million nine hundred and ninety thousand and one
$ cjam negate.cjam <<< -1001000000
one milliard and one million
$ cjam negate.cjam <<< 0
zero

Validity

All code is functional, so removing parts should not be possible. Note that all linefeeds are part of strings and cannot be removed.

There are no repeated sequences of six characters:

$ tr \\n \\t <negate.cjam | grep -P '(.{6}).*\1' | wc -c
0

How it works

I've started with a list of the first one thousand natural numbers and a list of the first three thousand three hundred and thirty-four powers of one thousand.

Sadly, both lists repeat the same 6 character sequences over and over again, so I had to encode them in a way that would avoid those repeated sequences. The following CJam code accomplishes that task:

q
2G#b
94b
{32+}%
{c}%
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}"
"}|{zyxwvutsrqponmlkjihgfedcba`_^]~[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#
! "
er

It reads the list from STDIN (q), converts the resulting string into a base 65536 number (2G#b), converts the resulting integer into an array by considering it a base 94 number (94b), adds 32 to each integer in the array ({32+}%) to avoid unprintable characters, converts the array into a string ({c}%) and performs a character transliteration ("…""…"er) to get rid of characters that require escaping. This required a little trial-and-error; the natural choice (95b) resulted in repeated sequences.

The final code does the following:

{                             " Define a decoding function for the lists.               ";
  "…""…"er{32-}%94b2G#b{c}%   " Perform the steps from above in reverse order.          ";
  "
  "/                          " Split the result by linefeeds.                          ";
}:D;

"…":H;"…":P;                  " Store the encoded lists in variables.                   ";

q~                            " Interpret the input from STDIN.                         ";
__                            " Duplicate twice.                                        ";
0<!{}{-1*}?                   " If the input is negative, multiply the last copy by -1. ";
`_                            " Stringify and duplicate the last copy.                  ";
,3%3\-"0"*\+                  " Prepend 0's to make the string length a multiple of 3.  ";
3/-1%                         " Split into string of three characters and reverse.      ";
-1:C;                         " Initialize variable C to -1. ";
{                             " For each substring:                                     ";
  ~                           " Interpret it (i.e., cast to integer).                   ";
  H=_                         " Retrieve the correspond English number from H.          ";
  'z'e'r"o"+++=               " Push 1 if the number is zero.                           ";
  C):C;                       " Increment C.                                            ";
  {;}{" "+CP=+}?              " Remove 0 or append the corresponding modifier from P.   ";
 }%
-1%_                          " Reverse the array and duplicate it.                     ";
,1>                           " If the array has more than one element…                 ";
{
  )_"and"/,1=                 " …and the last element doesn't contain the string 'and'… ";
  'a'n'd" "+++*\+a+           " …prepend the  string 'and ' to it.                      ";
}{_,0={H0=a+}*}?              " If the array is empty, replace it with [ 'zero' ].      ";
\0>                           " If the input was positive,                              ";
{
  'n'e'g'a't'i'v"e"+++++++a\+ " prepend the string 'negative'.                          ";
}{}?
" "*                          " Join the array of strings with spaces.                  ";
"
"                             " Append a linefeed.                                      ";

Dennis

Posted 2014-06-13T01:00:30.790

Reputation: 196 637

Do you think you could explain how you made this? – PyRulez – 2014-06-16T14:15:29.390

@PyRulez: I've edited my answer. – Dennis – 2014-06-16T18:53:32.580

1

Tcl, 1073741823 (1G-1 bytes, cheating)

This is (obviously) cheating. It can be even larger in some languages like Bash, which doesn't load the whole program when it starts. Tcl runs very slow at starting, and finally refuses to run the program if the file size is about 2147483647 bytes or more.

set b binary
$b scan [$b format i [expr {[gets stdin]-1^3+[file size $argv0]*4}]] i a
puts $a
exit
#!!!!!#"!!!!#%!!!!#&!!!!#'!!!!#(!!!!#)!!!!#*!!!!#+!!!!#,!!!!#-!!!!#.!!!!#/!!!!#0!!!!#1!!!!#2!!!!#3!!!!#4!!!!#5!!!!#6!!!!#7!!!!#8!!!!#9!!!!#:!!!!#<!!!!#=!!!!#>!!!!#?!!!!#@!!!!#A!!!!#B!!!!#C!!!!#D!!!!#E!!!!#F!!!!#G!!!!#H!!!!#I!!!!#J!!!!#K!!!!#L!!!!#M!!!!#N!!!!#O!!!!#P!!!!#Q!!!!#R!!!!#S!!!!#T!!!!#U!!!!#V!!!!#W!!!!#X!!!!#Y!!!!#Z!!!!#[!!!!#^!!!!#_!!!!#`!!!!#a!!!!#b!!!!#c!!!!#d!!!!#e!!!!#f!!!!#g!!!!#h!!!!#i!!!!#j!!!!#k!!!!#l!!!!#m!!!!#n!!!!#o!!!!#p!!!!#q!!!!#r!!!!#s!!!!#t!!!!#u!!!!#v!!!!#w!!!!#x!!!!#y!!!!#z!!!!#{!!!!#|!!!!#~!!!!#!"!!!#""!!!#%"!!!#&"!!!#'"!!!#("!!!#)"!!!#*"!!!#+"!!!#,"!!!#-"!!!#."!!!#/"!!!#0"!!!#1"!!!#2"!!!#3"!!!#4"!!!#5"!!!#6"!!!#7"!!!#8"!!!#9"!!!#:"!!!#<"!!!#="!!!#>"!!!#?"!!!#@"!!!#A"!!!#B"!!!#C"!!!#D"!!!#E"!!!#F"!!!#G"!!!#H"!!!#I"!!!#J"!!!#K"!!!#L"!!!#M"!!!#N"!!!#O"!!!#P"!!!#Q"!!!#R"!!!#S"!!!#T"!!!#U"!!!#V"!!!#W"!!!#X"!!!#Y"!!!#Z"!!!#["!!!#^"!!!#_"!!!#`"!!!#a"!!!#b"!!!#c"!!!#
(...1073740323 more bytes...)
|%#m+Y|%#n+Y|%#o+Y|%#p+Y|%#q+Y|%#r+Y|%#s+Y|%#t+Y|%#u+Y|%#v+Y|%#w+Y|%#x+Y|%#y+Y|%#z+Y|%#{+Y|%#|+Y|%#~+Y|%#!,Y|%#",Y|%#%,Y|%#&,Y|%#',Y|%#(,Y|%#),Y|%#*,Y|%#+,Y|%#,,Y|%#-,Y|%#.,Y|%#/,Y|%#0,Y|%#1,Y|%#2,Y|%#3,Y|%#4,Y|%#5,Y|%#6,Y|%#7,Y|%#8,Y|%#9,Y|%#:,Y|%#<,Y|%#=,Y|%#>,Y|%#?,Y|%#@,Y|%#A,Y|%#B,Y|%#C,Y|%#D,Y|%#E,Y|%#F,Y|%#G,Y|%#H,Y|%#I,Y|%#J,Y|%#K,Y|%#L,Y|%#M,Y|%#N,Y|%#O,Y|%#P,Y|%#Q,Y|%#R,Y|%#S,Y|%#T,Y|%#U,Y|%#V,Y|%#W,Y|%#X,Y|%#Y,Y|%#Z,Y|%#[,Y|%#^,Y|%#_,Y|%#`,Y|%#a,Y|%#b,Y|%#c,Y|%#d,Y|%#e,Y|%#f,Y|%#g,Y|%

It computes the result with its own file size. So deleting anything will change the behavior.

The above program is generated by the C++ program below.

#include<fstream>
#include<string>
#include<cstring>

std::ofstream f("a.tcl");
const long long size = 0x3fffffffLL;

const std::string init = "set b binary\n"
             "$b scan [$b format i [expr {[gets stdin]-1^3+[file size $argv0]*4}]] i a\n"
             "puts $a\n"
             "exit\n";
const std::string charset = "!\"%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[^_`abcdefghijklmnopqrstuvwxyz{|~";
const int ncharset = 88;

int main() {
    f<<init;
    long long p = init.length();

    int b[5] = {};
    char ch[6] = "!!!!!";

    while(p < size) {
        f<<"#";
        p++;
        if(size-p > 5) {
            f.write(ch, 5);
            p += 5;
        }
        else {
            f.write(ch, size-p);
            break;
        }
        int i=0;
        while(b[i] == ncharset-1) {
            ch[i] = charset[b[i]=0];
            i++;
        }
        ch[i] = charset[++b[i]];
    }
    f<<std::flush;
    return 0;
}

The 7-zipped version of the complete program has only 18MB. Maybe I can upload it somewhere if someone request for it.

I chose Tcl because it has only a small number of special characters. So I could be sure one cannot implement the same functionality by selecting some characters not to delete. I guess Lisp is better on this.

jimmy23013

Posted 2014-06-13T01:00:30.790

Reputation: 34 042

(new to code bowling) Why is this cheating? – gregsdennis – 2017-05-26T06:48:04.920

0

C# 865

Uses DateTime parsing since a negative will throw an exception. Since Console was already used the answer is output to a Form. Also C# has string and String object.

Edit: removed some duplicate char sequences.

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Diagnostics;
using System.Globalization;
namespace Golf
{ 
    class Code
    {
        String num;
        bool isPos;
        Code() { }
        void In()
        {
            num = Console.ReadLine();
        }

        void Out()
        {
            try
            {
                DateTime.Parse(this.num);
                isPos = true;
            }
            catch (Exception)//if negative throw exception
            {
                isPos = false;
            }
            int res;
            double pi = Math.PI;
            if(Int32.TryParse(num, out res))
            {
                res = (int)((isPos) ? Math.Cos(pi) * res : Math.Sin(3 * pi / 2) * res);
            }

            Form f = new Form();
            Label l = new Label();
            l.Text = res.ToString();
            f.Controls.Add(l);
            f.ShowDialog();
        }

        public static void Main(string[] args)
        {
            Code code = new Code();
            code.In();
            code.Out();          
        }

    }
}

bacchusbeale

Posted 2014-06-13T01:00:30.790

Reputation: 1 235