49
\$\begingroup\$

Your Programs:

You'll write two programs (both in the same language). The storage program takes a string from STDIN and stores it somewhere persistent (see below) and then exits without error. The retrieval program takes no input, retrieves the string that was stored, and prints it to STDOUT.

Objective test of Persistence:

You should be able to run the storage program on your local machine, then power-cycle your local machine, then call the retrieval program on your local machine. You can stash the string however you want (even on the web) as long as you pass this reboot test.

Test Cases:

Storage then retrieval:

echo foo | Store
Retrieve
foo

Repeated Stores should overwrite (like a set() method):

echo foo | Store
echo bar | Store
Retrieve
bar

Repeated Retrieval is non-destructive (like a get() method):

echo foo | Store
Retrieve
foo
Retrieve
foo

Retrieval before any invocation of Storage:

You don't need to worry about this. Your retrieval program can assume that the storage program has been run at some point in the past.

Input/Output flexibility.

People have asked me to expand this from strict STDIN/STDOUT to the standard IO rules. I can't because it would introduce too many loopholes. Some standard IO options already have the input stored in a persistent way, eg "programs may take input from a file". I'd like to be more flexible than just strict STDIN and STDOUT, but without opening the floodgates.

From the standard IO rules thread I'm cherry-picking the ones that don't break the challenge:

If you use an alternate it must be user-interactive. The user shouldn't have to do any other work besides piping their input to your program, typing it into a prompt your program provides, or typing input as a command-line-arg of your program. The user shouldn't have to do anything other than running your retrieve program to see the output displayed on screen or sent to STDOUT or STDERR.

Allowed assumptions:

  • Your two programs will be run in the same directory
  • Your programs have read-write permissions for that directory
  • Files you create will survive the reboot (not in a temp dir)
  • One trailing newline that wasn't part of the string is allowed. No other trailing whitespace

This is code-golf, and your score is the sum of bytes from both programs.

\$\endgroup\$
21
  • 1
    \$\begingroup\$ You can stash the string however you want (even on the web) I'm not pretty sure that this should be valid. \$\endgroup\$ Commented Jul 5, 2018 at 23:26
  • 9
    \$\begingroup\$ so just echo $@>x and cat x is valid? \$\endgroup\$
    – Adám
    Commented Jul 5, 2018 at 23:30
  • 4
    \$\begingroup\$ @EriktheOutgolfer Why would it not be valid? Even if there is a loophole discussed on meta that doesn't prevent a challenge from specifically allowing it. \$\endgroup\$
    – dylnan
    Commented Jul 5, 2018 at 23:45
  • 6
    \$\begingroup\$ Web restrictions are usually about pulling stuff from the web as a loophole to get out of doing the work of creating that stuff. In this case, if it's on the web it's because you did the work of putting it there. \$\endgroup\$
    – Jared K
    Commented Jul 6, 2018 at 0:18
  • 3
    \$\begingroup\$ Somebody needs to write an answer for a computer with magnetic-core memory. \$\endgroup\$
    – Mark
    Commented Jul 6, 2018 at 23:30

41 Answers 41

89
\$\begingroup\$

zsh, 4 bytes

Store: >f (reads from STDIN and writes to a file called f)
Retrieve: <f (writes the contents of f to STDOUT)

\$\endgroup\$
4
  • 8
    \$\begingroup\$ I think we have a winner. \$\endgroup\$
    – Adám
    Commented Jul 6, 2018 at 0:06
  • \$\begingroup\$ @Adám unless there is a token to write input to file in 1 byte :P \$\endgroup\$ Commented Jul 6, 2018 at 0:08
  • 1
    \$\begingroup\$ @FreezePhoenix There is probably none unless you write a new language now which is not allowed... \$\endgroup\$
    – Chromium
    Commented Jul 6, 2018 at 10:37
  • 5
    \$\begingroup\$ @Chromium check Z80 answer: some existing languages can write from a 0 bytes program. \$\endgroup\$
    – Cœur
    Commented Jul 6, 2018 at 16:20
57
\$\begingroup\$

TI-BASIC (Z80), 1 byte?

Store:  (just enter the string)
Retrieve: Ans (byte 27)

But if that isn't valid:

TI-BASIC (Z80), 7 6 bytes

-1 thanks to Jakob.

Store: Prompt Str0 (bytes DD AA 09)
Retrieve: disp Str0 (bytes ED AA 09)

\$\endgroup\$
15
  • 1
    \$\begingroup\$ Are you sure that's 5 bytes? \$\endgroup\$ Commented Jul 5, 2018 at 23:49
  • 6
    \$\begingroup\$ @FreezePhoenix TI-Basic uses tokens. \$\endgroup\$
    – Adám
    Commented Jul 5, 2018 at 23:53
  • 3
    \$\begingroup\$ Hmm...Why not take input through Ans and persist it in the same variable? An empty store program and just Ans for retrieve should work: 1 byte! \$\endgroup\$
    – Jakob
    Commented Jul 6, 2018 at 5:23
  • 9
    \$\begingroup\$ @Arthur Yep, Ans persists. In fact, a lot of state persists, including (I think) all user variables, equations, and history. From the user's perspective, powered off is basically the TI calculator equivalent of a sleep state for a PC, so it doesn't disrupt much. \$\endgroup\$
    – Jakob
    Commented Jul 6, 2018 at 15:29
  • 2
    \$\begingroup\$ @JaredK I definitely agree that the 1-byte solution smells of rule abuse (even though I was the one who suggested it). However, I would say the store program exits, since other programs can be run after it (though they interfere with the operation of the solution). My interpretation of your "objective test of persistence" was that the programs would be run directly before and after the power cycle. If that is incorrect, perhaps you could require the 1-byte solution to be marked noncompeting? \$\endgroup\$
    – Jakob
    Commented Jul 7, 2018 at 21:57
24
\$\begingroup\$

Browser JS, 44 bytes

Store:

localStorage.a=prompt()

Retrieve:

alert(localStorage.a)
\$\endgroup\$
10
  • \$\begingroup\$ Will prompt() read from STDIN? \$\endgroup\$
    – pipe
    Commented Jul 6, 2018 at 11:19
  • 9
    \$\begingroup\$ Does a graphical web browser have an STDIN? No. prompt() pops up an alert that asks for you to enter text, and returns the result. \$\endgroup\$
    – Dev
    Commented Jul 6, 2018 at 12:40
  • 5
    \$\begingroup\$ @Dev Of course a graphical web browser have a STDIN, just like every other process. If you can't use it from a specific language is another question and if the answer is "No", then I maybe it can be used in this challenge. \$\endgroup\$
    – pipe
    Commented Jul 6, 2018 at 14:02
  • 5
    \$\begingroup\$ @Dev The default I/O methods include input via GUI prompt and output via GUI display. Unless OP meant to override the standard, this should be valid. I'll clarify. \$\endgroup\$ Commented Jul 6, 2018 at 16:29
  • 2
    \$\begingroup\$ I've edited the challenge to allow more IO, but I'm only expanding it to a limited subset of the default IO methods. This answer is within my subset though. I like it. \$\endgroup\$
    – Jared K
    Commented Jul 6, 2018 at 17:52
20
\$\begingroup\$

POSIX shell sh/bash/... 8 bytes

store:

dd>f

get:

dd<f
\$\endgroup\$
1
12
\$\begingroup\$

Python 3, 46 bytes

store, 45 bytes:

open(*'fw').write('print(%r)'%open(0).read())

The retrieve program is built by the store command, a file named f. (1 byte for the file name)

\$\endgroup\$
6
  • 2
    \$\begingroup\$ Surely you can use input()? \$\endgroup\$
    – Miriam
    Commented Jul 6, 2018 at 21:28
  • \$\begingroup\$ @ArtemisFowl input() only receives up to the first newline. open(0).read reads all of STDIN \$\endgroup\$
    – Jo King
    Commented Jul 22, 2018 at 8:53
  • \$\begingroup\$ You probably posted when things were still ambiguous, but as-is this answer doesn't meet the current spec. I originally intended the STDIN/STDOUT requirement to be strict, with defaults not allowed. I've expanded it, but only to a subset of the defaults. Your retrieve program, if it doesn't use STDOUT, still needs to display the output on screen. If I allowed the full defaults, the solution for every language would be 'takes input in a file' , 'gives output in a file', zero bytes. \$\endgroup\$
    – Jared K
    Commented Jul 24, 2018 at 16:50
  • \$\begingroup\$ @JaredK I don't think you quite get how this works. The store-program reads the input from STDIN and then stores a Python program that prints this input in f. Example: STORE is called with an input of abc. It then writes print('abc') to f. If you now call f (RETRIEVE), it prints abc to STDOUT. \$\endgroup\$
    – ovs
    Commented Jul 24, 2018 at 17:32
  • \$\begingroup\$ @JaredK I asked you in a comment whether it was allowed to for STORE to modify RETRIEVE. \$\endgroup\$
    – ovs
    Commented Jul 24, 2018 at 17:33
10
\$\begingroup\$

Batch, 16 bytes

COPY CON A
TYPE A
\$\endgroup\$
8
\$\begingroup\$

Powershell - 4 Bytes

Storage:

ac

(alternative also sc)

Retrieval

gc

Edit: I just noticed the output is not allowed any user input... so it jumps from 4 to either 6 or 8 bytes

Storage:

ac f

(alternative also sc f) for the 8 byte version

ac

(and specify f as path) for the 6 byte Version

Retrieval

gc f
\$\endgroup\$
0
8
\$\begingroup\$

Rust, 136 bytes

Store (84 bytes)

use std::{fs::*,io::*};

||{let mut v=vec![];stdin().read_to_end(&mut v);write("a",v)}

Retrieve (52 bytes)

||print!("{}",std::fs::read_to_string("a").unwrap())

Acknowledgments

\$\endgroup\$
5
  • 1
    \$\begingroup\$ You can save a byte by changing the import to use std::{io::*,fs::*} and then using write instead of std::fs::write. \$\endgroup\$ Commented Jul 6, 2018 at 16:42
  • \$\begingroup\$ How about write("a",String::from_iter(stdin().chars()))? \$\endgroup\$
    – Bergi
    Commented Jul 8, 2018 at 16:51
  • \$\begingroup\$ @Bergi Nice. But chars triggers error[E0658]: use of unstable library feature 'io' in stable Rust. \$\endgroup\$
    – Jakob
    Commented Jul 8, 2018 at 17:25
  • \$\begingroup\$ Hm, it seems chars() is deprecated in favour of String::from_utf8(stdin().bytes()). (Also I used the nightly docs, not sure whether that's the culprit) \$\endgroup\$
    – Bergi
    Commented Jul 8, 2018 at 17:44
  • \$\begingroup\$ @Bergi I tried a few variations with bytes() or chars() but none of them were very short because the iterator item is wrapped in io::Result. \$\endgroup\$ Commented Jul 9, 2018 at 7:38
8
\$\begingroup\$

Bash, 12 11 10 bytes

store, 7 6 5 bytes

cat ->f # no need for -, stdin is default

cat >f # no need for space, > separates as well

cat>f

retrieve, 5 bytes

cat f
\$\endgroup\$
4
  • 1
    \$\begingroup\$ No need for - in the store program. \$\endgroup\$ Commented Jul 6, 2018 at 10:54
  • 2
    \$\begingroup\$ No need for the space between "cat" and ">", either! \$\endgroup\$
    – psmears
    Commented Jul 6, 2018 at 14:11
  • \$\begingroup\$ You should be able to do the same as in the zsh post for writing and use >f. I am not sure if <f is valid for reading, though. \$\endgroup\$
    – allo
    Commented Jul 10, 2018 at 12:01
  • \$\begingroup\$ @allo At least on Cygwin, >f works like echo '' > f (emptying the file if it exists, creating if it doesn't), while <f seems to be a no-op. \$\endgroup\$
    – Sundar R
    Commented Jul 20, 2018 at 12:04
7
\$\begingroup\$

HP 49G RPL, 48 bytes

To save: :2: A DUP PURGE STO, 26.5 bytes

To restore: :2: A RCL, 21.5 bytes

If we can leave in the backup battery, we get:

HP 49G RPL, 0 bytes

To save: , 0 bytes

To restore: , 0 bytes, since the HP 49G leaves the stack untouched across reboots.

\$\endgroup\$
6
  • \$\begingroup\$ The zero-byte solution should work for a variety of caluclators. I'll bust out my 42s when I get home. \$\endgroup\$ Commented Jul 7, 2018 at 23:15
  • \$\begingroup\$ I think your zero-byte solution, and the others being run on calculators that reboot non-destructively, are failing to meet two parts of the question: "You will make two programs." What you've got is a single program that survives the reboot. And "Store reads from STDIN and then exits without error." Your program is still waiting for the user to press a key. Your program's stack and execution state are still mutable. I think that means it is still running, and hasn't exited. \$\endgroup\$
    – Jared K
    Commented Jul 9, 2018 at 14:49
  • 1
    \$\begingroup\$ @JaredK The question never stipulated that the two programs couldn't be identical. As for the exiting part: traditionally in RPL input to programs is given on the stack. That is the standard input. \$\endgroup\$
    – Jason
    Commented Jul 9, 2018 at 15:36
  • 1
    \$\begingroup\$ Would the stack survive a power cycle? Maybe a soft power-off via the calculator's buttons, but I'm guess not removing the battery. So maybe it depends what a power cycle is. \$\endgroup\$
    – user
    Commented Jul 9, 2018 at 15:42
  • 1
    \$\begingroup\$ @user No, stack doesn't survive soft (ON+C) or hard reset (ON+A+F) (distinct from soft-power off, Right Shift+ON), unlike storing in port 2, which is flash memory (and survives soft and hard reset). Since the TI-BASIC answer seemed to use that definition I included the stack answer for completeness. \$\endgroup\$
    – Jason
    Commented Jul 9, 2018 at 15:44
6
\$\begingroup\$

APL (APLX), 5 bytes

Store: ⍞⍈1
Retrieve: ⍇1

 get line from stdin
⍈1 write to next available component of file number 1

⍇1 read the first* last component of file number 1

APLX Store sessionAPLX Retrieve session

* Documentation says first but experimentation shows last.

\$\endgroup\$
6
\$\begingroup\$

bash, 10 bytes (non-competing)

touch $@
ls

Unix filenames can contain any character except NUL and /, and their names can be upto 255 bytes long so this will be able to store only strings up to that length (consider that a limitation of the storage medium), and that don't contain '/' in them. That's one reason this is non-competing, another is that this assumes the directory it's run on is empty (or that extraneous output from ls is allowed). I still wanted to post this because it just seemed a cool and non-obvious way to store information.

Another on a similar vein, which wouldn't have the same length and character limitations would be:

35 33 bytes

mkdir -p $@
find|sed '$!d;s/..//'

This allows the / character in the string, and supports many more characters (exactly how many depends on implementation).

(-2 bytes on this thanks to @Cows quack)

\$\endgroup\$
4
  • 1
    \$\begingroup\$ IIRC, I believe that a group at Berkeley once created a database system back in the 1990s that stored table column data as filenames (up to 255 chars). I think the rows and tables were parent directories. \$\endgroup\$ Commented Jul 13, 2018 at 18:28
  • \$\begingroup\$ In your 35 byte answer, you can change the second statement to s/..//. The $ is not required because all other lines are deleted so this can only apply to the last line, and the ^ can be dropped because the substitution is only applied on the first match. \$\endgroup\$
    – user41805
    Commented Jul 20, 2018 at 8:26
  • \$\begingroup\$ @Cowsquack Done. Thanks for explaining why the change works, too. \$\endgroup\$
    – Sundar R
    Commented Jul 20, 2018 at 11:59
  • 1
    \$\begingroup\$ You need to use "$@", not $@, to avoid getting burned by whitespace, *, ?, or ~ characters. \$\endgroup\$ Commented Jul 21, 2018 at 15:46
5
\$\begingroup\$

Python 3, 56 bytes

Store (33 bytes)

open(*'aw').write(open(0).read())

Retrieve (23 bytes)

print(open('a').read())

Prints with a trailing newline.

\$\endgroup\$
5
  • \$\begingroup\$ why not input() instead of open(0).read() and omit end= from print? \$\endgroup\$
    – MoxieBall
    Commented Jul 6, 2018 at 14:33
  • \$\begingroup\$ @MoxieBall Not sure about why input wasn't used, but omitting end= would result in a new line being added to the end of the string (i.e., not the original string) (maybe) \$\endgroup\$
    – user52452
    Commented Jul 6, 2018 at 15:03
  • \$\begingroup\$ @NickA It looks like a newline gets printed in the question, anyways, so I don't think that should matter... \$\endgroup\$
    – MoxieBall
    Commented Jul 6, 2018 at 15:14
  • \$\begingroup\$ Have I gone crazy or does 23+33=56 (not 54)? Also why not use input()? \$\endgroup\$
    – Miriam
    Commented Jul 6, 2018 at 21:23
  • 1
    \$\begingroup\$ @ArtemisFowl Good catch. As for input, I assume that the string to persist may contain newlines. \$\endgroup\$
    – Jakob
    Commented Jul 6, 2018 at 21:32
4
+50
\$\begingroup\$

Japt, 46 30 bytes

-16 bytes thanks to Shaggy.

One of the first times I've tried using Japt. The JS eval can be fidgety sometimes. Uses the browser's window.localStorage.

Store (16 bytes)

Ox`lo¯lSÈSge.P=U

Retrieve (14 bytes)

Ox`lo¯lSÈSge.P
\$\endgroup\$
4
  • \$\begingroup\$ +1 for being the first to use something other than standard file IO I like it. \$\endgroup\$
    – Jared K
    Commented Jul 6, 2018 at 4:31
  • 1
    \$\begingroup\$ Welcome to Japt! :) \$\endgroup\$
    – Shaggy
    Commented Jul 6, 2018 at 7:14
  • 1
    \$\begingroup\$ By the way, you can bypass setItem and getItem completely with localStorage.key. Set value, retrieve value \$\endgroup\$
    – Shaggy
    Commented Jul 6, 2018 at 12:04
  • \$\begingroup\$ @Shaggy Thanks! Yours also avoids the weirder control characters. \$\endgroup\$ Commented Jul 6, 2018 at 13:01
4
\$\begingroup\$

Haskell, 46 bytes

Store (26 bytes):

getContents>>=writeFile"t"

Retrieve (20 bytes):

readFile"t">>=putStr
\$\endgroup\$
3
\$\begingroup\$

Ruby (26 Bytes)

Set (16 Bytes)

IO.write'a',gets

Get (10 Bytes)

IO.read'a'
\$\endgroup\$
3
\$\begingroup\$

MATLAB (30 Bytes)

Set (22 Bytes)

a=input('','s');save a

Can shave off 4 bytes by changing to input(''), but this will require input to be in single quotes: 'input string'

Get (8 Bytes)

load a;a
\$\endgroup\$
3
\$\begingroup\$

C (GCC), 98 bytes

Store (46 bytes)

Input is via first command line argument.

main(c,v)char**v;{fputs(v[1],fopen("a","w"));}

Retrieve (52 bytes)

c,d;r(){for(d=open("a",0);read(d,&c,1);)putchar(c);}

Unportability

  • Requires that several pointer types fit in int.

Acknowledgments

\$\endgroup\$
3
  • 1
    \$\begingroup\$ This requires a C implementation where int can hold a pointer, for the implicit declaration of int fopen() to work. (e.g. most 32-bit systems, or use gcc -m32 if you're on x86-64 to make a 32-bit executable.) And BTW, I tried using Linux's sendfile and copy_file_range(2) system calls, but they don't work to/from a TTY. \$\endgroup\$ Commented Jul 9, 2018 at 7:56
  • 1
    \$\begingroup\$ Since you're writing functions, not programs, perhaps you could justify taking the input string as a function arg allowing fputs(fopen()), and read(open(),buf,-1). (The question now allows a command-line arg as input.) \$\endgroup\$ Commented Jul 9, 2018 at 7:57
  • \$\begingroup\$ The Linux 'splice' function copies from a pipe to a file (and vice-versa). If stdin/out are pipes, then it will save a function call, at the expense of more parameters. \$\endgroup\$
    – CSM
    Commented Jul 9, 2018 at 21:43
2
\$\begingroup\$

APL (Dyalog Unicode), 18 bytes

Store: ⍞⎕NPUT⎕A 1 Try it online!
Retrieve: ⊃⎕NGET⎕A Try it online!

 get line from stdin
⎕NPUT put it in a native file called
⎕A the uppercase alphabet 1 and overwrite if the file exists

 the first part (the data, the next parts are encoding and line ending type) of
⎕NGET get the native file
⎕A the uppercase alphabet

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

R (27 bytes)

store (21 bytes)

x=readLines('stdin')

load (6 bytes)

cat(x)

For this to work, the first script needs to be invoked with the command line option --save, and the second one with --restore (though in interactive mode this isn’t necessary: these options are the default).

This could be shortened by 7 bytes were it not for the fact that a bug in R prevents the default argument of readLine from working in non-interactive mode. In interactive mode, it is not necessary, and the solution therefore only uses 20 bytes.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ I think it would be much more efficient to use q directly, with the first program being x=scan(); q("y") and the second either x or cat(x) depending on how strict we want to be about how strings are printed. By the usual code golf rules you must also count command line arguments, so add bytes for --save and --restore (which my formulation doesn't need) \$\endgroup\$
    – JDL
    Commented Jul 6, 2018 at 12:56
  • \$\begingroup\$ @JDL scan doesn’t work for arbitrary contents, and scan(w='character') is longer than readLines(). q is unnecessary (but q('y') wouldn’t work, you have to spell it yes). I thought about just using x in the second program but this would violate the requirements, as far as I understand them. \$\endgroup\$ Commented Jul 6, 2018 at 13:53
  • 1
    \$\begingroup\$ you can use scan(w=""), you don't need to spell out the type, scan will infer it from the type of argument specified. For me, q("y") works as a save-inducing quit but perhaps that depends on your version of R, and possibly whether you are using Rstudio or not. \$\endgroup\$
    – JDL
    Commented Jul 6, 2018 at 14:45
  • \$\begingroup\$ @JDL scan: Oh, neat, the documentation doesn’t mention this! Unfortunately scan will still perform some parsing so this won’t work with all input. Anyway, scan('stdin',w='') happens to be the exact same length as readLines('stdin'). q: R 3.4.4 says “Error in q("y") : unrecognized value of 'save'”. \$\endgroup\$ Commented Jul 6, 2018 at 14:57
  • \$\begingroup\$ Ah, it's an Rstudio thing — I tried it in Rstudio and separately at the terminal and it only worked in Rstudio. \$\endgroup\$
    – JDL
    Commented Jul 9, 2018 at 12:53
2
\$\begingroup\$

Java (JDK 10), 204 Bytes

Warning: Overwrites any preferences that any java programs have stored for your username!

Store, 94 Bytes:

interface S{static void main(String[]a){java.util.prefs.Preferences.userRoot().put("",a[0]);}}

Try it online!

Retrieve 110 Bytes:

interface R{static void main(String[]a){System.out.print(java.util.prefs.Preferences.userRoot().get("",""));}}

Try it online!

java S foo
java R
foo

This works by taking input as an arg and storing it in the user preferences backing-store provided by java.util.prefs. It overwrites the user's root node to save one byte on naming a node. If you want to test it non-deestructively, either run it from a throwaway username or change the key from "" to a node name.

\$\endgroup\$
3
  • \$\begingroup\$ Good idea! Since you're using Java 10 you can shorten these by making them lambda expressions. Also if your byte count doesn't include z you should remove it from the programs and the TIO. Consider putting a warning at the top of the submission instead to warn people. For sure the TIO should have your 94- and 110-byte solutions. \$\endgroup\$
    – Jakob
    Commented Jul 9, 2018 at 13:27
  • \$\begingroup\$ Thanks! I made your suggested edits. I'm not certain but I don't think lambda expressions can fulfill the custom IO rules for this question. \$\endgroup\$
    – Jared K
    Commented Jul 9, 2018 at 15:18
  • \$\begingroup\$ D'oh. You're right, I forgot about that. \$\endgroup\$
    – Jakob
    Commented Jul 9, 2018 at 15:21
2
\$\begingroup\$

C#, 157 Bytes

Set, 74 Bytes:

class P{static void Main(string[]a){System.IO.File.WriteAllLines("a",a);}}

Get, 83 Bytes:

class P{static void Main(){System.Console.Write(System.IO.File.ReadAllText("a"));}}

-1 Bytes thanks to VisualMelon
-2 Bytes thanks to LiefdeWen

\$\endgroup\$
2
  • \$\begingroup\$ Remove that space after "a",, and I doubt this will be beaten :) \$\endgroup\$ Commented Jul 9, 2018 at 17:25
  • \$\begingroup\$ You can save another byte by using WriteAllLines and the second param a \$\endgroup\$
    – LiefdeWen
    Commented Jul 9, 2018 at 17:47
2
\$\begingroup\$

Perl 5, 48 26 23 bytes

Write, 20+1(-n) bytes

-3 bytes thanks to mob

open f,">>f";print f

I'm actually not certain about this one points-wise, but it meets the criteria. For past entries, only the cli options were counted, so that's what I'm going with.

Read, 0+2 bytes

perl -pe "" f
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Why did you score -ne with 1 (it should have an e too), but -pe with 2? You could use -E and say instead of print. \$\endgroup\$
    – simbabque
    Commented Jul 9, 2018 at 12:02
  • \$\begingroup\$ Thank you for letting me know about -E, I wasn't familiar with that one. As for why I didn't go with -ne, it is because for that one, I'm actually running from a file. So, it would look like perl -n w.pl If this goes against PCG community standards though, I can edit my answer accordingly. \$\endgroup\$
    – Bee H.
    Commented Jul 9, 2018 at 14:07
  • \$\begingroup\$ No, it's fine. We add a malus for extra command line arguments, so it's fine. \$\endgroup\$
    – simbabque
    Commented Jul 9, 2018 at 14:30
  • 2
    \$\begingroup\$ ">>","f" --> ">>f" saves 3 char \$\endgroup\$
    – mob
    Commented Jul 10, 2018 at 0:27
2
\$\begingroup\$

Sed, 2+2 bytes:

Stores to file f:

wf

Reads from file f:

rf

Try a demo online!

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

Attache, 23 + 16 = 39 bytes

Simply writes STDIN to file A, then reads file A.

store.@:

$A&FileWrite!AllInput[]

retrieve.@:

Echo!FileRead!$A

Testing

C:\Users\conorob\Programming\attache (master -> origin)
λ echo testing | attache store.@

C:\Users\conorob\Programming\attache (master -> origin)
λ attache retrieve.@
testing
\$\endgroup\$
1
\$\begingroup\$

Lua, 57 53 51 bytes

Store, 27 bytes

io.open("x","w"):write(...)

Retrieve, 24 bytes

print(io.open"x":read())
\$\endgroup\$
1
\$\begingroup\$

RUBY

Store (24 bytes)

File.write('a', ARGV[0])

Retrieve (16 bytes)

p File.read('a')
\$\endgroup\$
3
  • 4
    \$\begingroup\$ The question asks for storing input from STDIN, not the arguments \$\endgroup\$
    – Ferrybig
    Commented Jul 6, 2018 at 12:38
  • \$\begingroup\$ I've since edited to allow IO alternates including arguments. \$\endgroup\$
    – Jared K
    Commented Jul 6, 2018 at 17:59
  • 1
    \$\begingroup\$ File.write'a',gets and p File.read'a' are a bit shorter ;) \$\endgroup\$ Commented Jul 7, 2018 at 15:08
1
\$\begingroup\$

C (Unix/GNU), 23+23 = 46 bytes

Store, 2723 bytes

main(){system("dd>f");}

Retrieve, 2723 bytes

main(){system("dd<f");}

This basically wraps jofel's answer into a C program.

Note: The dd commands outputs some statistics to stderr, so you will see some additional output when you naively run it in the shell. However, since the challenge only says that the stored string must be presented on stdout, not stderr, I take it that it is allowed to have additional output on stderr... Anyway, suppressing stderr output is as easy as replacing dd with cat, increasing the byte counts of the two programs by one, each.

\$\endgroup\$
2
  • \$\begingroup\$ Depending on your compiler you may also be able to remove the int return type from main. In old ANSI C style int is the default return type. \$\endgroup\$
    – Jakob
    Commented Jul 9, 2018 at 19:48
  • \$\begingroup\$ @Jakob Ah, yes, of course. I relied conciously on the implicit declaration of system() and forgot about that of main() - ouch. Thanks for pointing that out :-) \$\endgroup\$ Commented Jul 9, 2018 at 22:15
1
\$\begingroup\$

PHP, 26+1 + 21 = 48 bytes

Store.php:

<?fputs(fopen(s,w),$argn);

Run with echo <input> | php -nF Store.php.

Retrieve.php:

<?=fgets(fopen(s,r));

Run with php -n Retrieve.php.

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

C (gcc), 77 67 + 25 = 92 bytes

Compiles with only a few warnings on my gcc.

store.c

#include<stdio.h>
main(int c,char**v){fputs(v[1],fopen("f","w"));}

Can probably golf out the include, but I couldn't figure out how. Segfaults if you don't pass it anything, but whatever.

Peter Cordes: -1

read.c

main(){system("cat f");}
\$\endgroup\$
4
  • \$\begingroup\$ int*f=fopen should work, i.e. lie to your compiler about the pointer type. But only if you compile for a 32-bit system (i.e. one where int can hold a pointer, like gcc -m32, or just gcc on a fully 32-bit system). You can also declare main as main(int c,char**v), or maybe int**v because you're not dereferencing. \$\endgroup\$ Commented Jul 9, 2018 at 7:22
  • \$\begingroup\$ The main(int c,char**v) works. I also realized I can do fputs(v[1],fopen("f","w"), although it still needs stdio for some reason. \$\endgroup\$ Commented Jul 9, 2018 at 14:14
  • \$\begingroup\$ It should work if you compile a 32-bit executable. For x86-64, the compiler will truncate the int return value to 32 bits, then sign-extend that as a pointer. If the returned FILE* is in the low 32 bits, it would work, but that's not the case on x86-64 Linux. \$\endgroup\$ Commented Jul 9, 2018 at 19:30
  • \$\begingroup\$ If you are on a system where all pointers are equal in size (rather likely), you can avoid the include by declaring fopen manually. Going old school with the arguments saves some bytes too: *fopen();main(c,v)int**v;{fputs(v[1],fopen("f","w"));}. \$\endgroup\$
    – gastropner
    Commented Jul 24, 2018 at 17:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.