Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

/prog/ challenge n+1: My other car

Name: Anonymous 2021-03-26 16:54

The goal

The goal is to implement LISP's car/cdr[1] family of functions. Write a program that receives two inputs on the standard input, separated by spaces: the first (cudder) is an accessor in the form of ``c[ad]{0,32}r''. The second is a LISP-style sexp[2], containing integers, potentially nested. Your program should execute the cudder on the sexp and print the result to standard output.

Assumptions

* The cudder will always be provided in such a way that the result is non-NIL/non-NuRuPo.
* Maximum nesting level is 8 levels deep.

Examples

./cudder cdr "(1 2 3 4)"
(2 3 4)
./cudder car "(1 2 3 4)"
1
./cudder cddr "(1 2 3 4)"
(3 4)
./cudder cdddr "(1 2 3 4)"
(4)
./cudder cadr "(1 2 3 4)"
2
./cudder car "((1) 2 3 4)"
(1)
./cudder caar "((1) 2 3 4)"
1
./cudder cadr "(1 (2 3 4))"
(2 3 4)


[1] https://en.wikipedia.org/wiki/CAR_and_CDR
[2] https://en.wikipedia.org/wiki/S-expression#Use_in_Lisp

Name: Anonymous 2021-03-26 16:59

#define car(x,...) x
#define cdr(x,...) __VA_ARGS__
#define cddr(...) cdr(cdr(__VA_ARGS__))
#define caar(...) car(car(__VA_ARGS__))
#define cdar(...) cdr(car(__VA_ARGS__))
#define cadr(...) car(cdr(__VA_ARGS__))

Name: Anonymous 2021-03-26 17:16

>>2
c[ad]{0,32}r
That's a lot of #defines

Name: Anonymous 2021-03-26 17:23

POOR STALLMAN

Name: Anonymous 2021-03-26 17:52

>>1 i'm not going to write a LITHP interpreter.
However you'll probably like this small program that will handle it:
https://github.com/kristianlm/small-lisp

Name: Anonymous 2021-03-26 19:06

>>5
malloc(), but no free(), beside
under the terms of the GNU General Public License as published by the Free Software Foundation

Ok.

Name: Anonymous 2021-03-26 19:13

>>6
fprintf(stderr, "%d bytes left hanging\n", total_malloc);

Name: Anonymous 2021-03-26 20:00

>>7
FREE AS IN FREEDOM!!!!

Name: Anonymous 2021-03-27 13:02

This is the last progchallenge i have poasted. Fuck this place.

Name: Anonymous 2021-03-28 1:30

>>9
Where's your own submission?

Name: Anonymous 2021-03-28 2:58

That was fun
#include<stdio.h>
#include<ctype.h>

int nothing(int c){
return 0;
}

int countpar(int c){
static int par=0;
if(c=='('){
++par;
}
if(c==')'){
if(!par--)
return 0;
}
putchar(c);
return 0;
}

int satisfy(int f(int), int act(int)){
int c;
int i=0;
while((c=getchar())!=EOF)
if(!f(c)){
ungetc(c, stdin);
break;
}else{
++i;
act(c);
}
return i;
}

int expect1(int x){
int c=getchar();
if (x==c)
return 1;
else{
ungetc(c, stdin);
return 0;
}
}

int element(int act(int)){
satisfy(isspace,nothing);
if(expect1('(')){
act('(');
while(element(act))
satisfy(isspace, putchar);
}
else if(expect1(')')){
act(')');
return 0;
}
else
satisfy(isdigit,act);
return 1;
}

int main(int argc, char *argv[]){
int status;
argv[1]++; /* c */
expect1('(');
while(*argv[1]!='r')
switch(*argv[1]++){
case 'd':
element(nothing);
status=0;
break;
case 'a':
satisfy(isspace,nothing);
if(expect1('('))
status=1;
else{
satisfy(isdigit,putchar);
status=2;
}
}
if(!status){
while (element(countpar));
}
else if(status == 1){
ungetc('(',stdin);
element(putchar);
}
putchar('\n');
}

Name: Anonymous 2021-03-28 4:47

new and improved
#include<stdio.h>
#include<ctype.h>

#define DECL(ret, name, ...) \
struct name { \
ret (*f)(struct name *,__VA_ARGS__); \
void *p; \
}

#define CALL(closure, ...) closure.f(&closure,__VA_ARGS__)

DECL(int,ii,int);

int nothing(int c){
return 0;
}

struct callf{
int (*f)(int);
};

int callf(struct ii *closure, int c){
struct callf *p=closure->p;
return p->f(c);
}

struct addspace{
int flag;
struct ii act;
};

int addspace(struct ii *closure, int c){
struct addspace *p=closure->p;
if(p->flag){
p->flag=0;
CALL(p->act,' ');
}
return CALL(p->act,c);
}

const struct ii myisdigit={callf,&(struct callf){isdigit}};
const struct ii myisspace={callf,&(struct callf){isspace}};
const struct ii mynothing={callf,&(struct callf){nothing}};

int satisfy(struct ii check, struct ii act){
int c;
int i=0;
while((c=getchar())!=EOF)
if(!CALL(check,c)){
ungetc(c,stdin);
break;
}else{
++i;
CALL(act,c);
}
return i;
}

int expect1(int x){
int c=getchar();
if (x==c)
return 1;
else{
ungetc(c, stdin);
return 0;
}
}

int elementloop(struct ii act1, struct ii act2);
int element(struct ii act1, struct ii act2){
if(expect1(')')){
CALL(act1,')');
return 0;
} else if(expect1('(')){
CALL(act2,'(');
satisfy(myisspace,mynothing);
return elementloop(act1,act2);
} else
satisfy(myisdigit,act2);
return 1;
}

int elementloop(struct ii act1, struct ii act2){
struct addspace addspaceinfo={1,act2};
struct ii myaddspace={addspace,&addspaceinfo};
if(element(act1,act2))
do{
satisfy(myisspace,mynothing);
addspaceinfo.flag=1;
}while(element(act1,myaddspace));
return 1;
}

int main(int argc, char *argv[]){
int status;
const struct ii myputchar={callf,&(struct callf){putchar}};
argv[1]++; /* c */
expect1('(');
while(*argv[1]!='r'){
satisfy(myisspace,mynothing);
switch(*argv[1]++){
case 'd':
element(mynothing,mynothing);
status=0;
break;
case 'a':
if(expect1('('))
status=1;
else{
satisfy(myisdigit,myputchar);
status=2;
}
}
}
if(!status){
satisfy(myisspace,mynothing);
putchar('(');
elementloop(myputchar,myputchar);
}
else if(status==1){
ungetc('(',stdin);
element(myputchar,myputchar);
}
putchar('\n');
}
Edited on 28/03/2021 05:01.

Name: Anonymous 2021-03-28 4:53

>>12 its now 1/4 the size of small-lisp interpreter in >>5

Name: Anonymous 2021-03-28 5:01

newest
#include<stdio.h>
#include<ctype.h>

#define DECL(ret, name, ...) \
struct name { \
ret (*f)(struct name *,__VA_ARGS__); \
void *p; \
}

#define CALL(closure, ...) closure.f(&closure,__VA_ARGS__)

DECL(int,ii,int);

int nothing(int c){
return 0;
}

struct callf{
int (*f)(int);
};

int callf(struct ii *closure, int c){
struct callf *p=closure->p;
return p->f(c);
}

struct addspace{
int flag;
struct ii act;
};

int addspace(struct ii *closure, int c){
struct addspace *p=closure->p;
if(p->flag){
p->flag=0;
CALL(p->act,' ');
}
return CALL(p->act,c);
}

const struct ii myisdigit={callf,&(struct callf){isdigit}};
const struct ii myisspace={callf,&(struct callf){isspace}};
const struct ii mynothing={callf,&(struct callf){nothing}};

int satisfy(struct ii check, struct ii act){
int c;
int i=0;
while((c=getchar())!=EOF)
if(!CALL(check,c)){
ungetc(c,stdin);
break;
}else{
++i;
CALL(act,c);
}
return i;
}

int expect1(int x){
int c=getchar();
if (x==c)
return 1;
else{
ungetc(c, stdin);
return 0;
}
}

int elementloop(struct ii act1, struct ii act2);
int element(struct ii act1, struct ii act2){
if(expect1(')')){
CALL(act1,')');
return 0;
} else if(expect1('(')){
CALL(act2,'(');
satisfy(myisspace,mynothing);
return elementloop(act1,act2);
} else
satisfy(myisdigit,act2);
return 1;
}

int elementloop(struct ii act1, struct ii act2){
struct addspace addspaceinfo={1,act2};
struct ii myaddspace={addspace,&addspaceinfo};
if(element(act1,act2))
do{
satisfy(myisspace,mynothing);
addspaceinfo.flag=1;
}while(element(act1,myaddspace));
return 1;
}

int main(int argc, char *argv[]){
int status;
const struct ii myputchar={callf,&(struct callf){putchar}};
argv[1]++; /* c */
expect1('(');
while(*argv[1]!='r'){
satisfy(myisspace,mynothing);
switch(*argv[1]++){
case 'd':
element(mynothing,mynothing);
status=0;
break;
case 'a':
if(expect1('('))
status=1;
else{
satisfy(myisdigit,myputchar);
status=2;
}
}
}
if(!status){
satisfy(myisspace,mynothing);
putchar('(');
elementloop(myputchar,myputchar);
}
else if(status==1){
ungetc('(',stdin);
element(myputchar,myputchar);
}
putchar('\n');
}

Name: Anonymous 2021-03-28 5:02

>>13
does not have cdaar

Name: Anonymous 2021-03-28 5:03

Last example looks wrong, cadr "(1 (2 3 4))" should be 2

Name: Anonymous 2021-03-28 5:15

>>16
I was going left to right (cdar would do what cadr does in >>1). Here is a fixed version:
#include<stdio.h>
#include<ctype.h>
#include<string.h>

#define DECL(ret, name, ...) \
struct name { \
ret (*f)(struct name *,__VA_ARGS__); \
void *p; \
}

#define CALL(closure, ...) closure.f(&closure,__VA_ARGS__)

DECL(int,ii,int);

int nothing(int c){
return 0;
}

struct callf{
int (*f)(int);
};

int callf(struct ii *closure, int c){
struct callf *p=closure->p;
return p->f(c);
}

struct addspace{
int flag;
struct ii act;
};

int addspace(struct ii *closure, int c){
struct addspace *p=closure->p;
if(p->flag){
p->flag=0;
CALL(p->act,' ');
}
return CALL(p->act,c);
}

const struct ii myisdigit={callf,&(struct callf){isdigit}};
const struct ii myisspace={callf,&(struct callf){isspace}};
const struct ii mynothing={callf,&(struct callf){nothing}};

int satisfy(struct ii check, struct ii act){
int c;
int i=0;
while((c=getchar())!=EOF)
if(!CALL(check,c)){
ungetc(c,stdin);
break;
}else{
++i;
CALL(act,c);
}
return i;
}

int expect1(int x){
int c=getchar();
if (x==c)
return 1;
else{
ungetc(c, stdin);
return 0;
}
}

int elementloop(struct ii act1, struct ii act2);
int element(struct ii act1, struct ii act2){
if(expect1(')')){
CALL(act1,')');
return 0;
} else if(expect1('(')){
CALL(act2,'(');
satisfy(myisspace,mynothing);
return elementloop(act1,act2);
} else
satisfy(myisdigit,act2);
return 1;
}

int elementloop(struct ii act1, struct ii act2){
struct addspace addspaceinfo={1,act2};
struct ii myaddspace={addspace,&addspaceinfo};
if(element(act1,act2))
do{
satisfy(myisspace,mynothing);
addspaceinfo.flag=1;
}while(element(act1,myaddspace));
return 1;
}

int main(int argc, char *argv[]){
int status;
const struct ii myputchar={callf,&(struct callf){putchar}};
argv[1] += strlen(argv[1]) - 1;
expect1('(');
while(*argv[1]!='c'){
satisfy(myisspace,mynothing);
switch(*argv[1]--){
case 'd':
element(mynothing,mynothing);
status=0;
break;
case 'a':
if(expect1('('))
status=1;
else{
satisfy(myisdigit,myputchar);
status=2;
}
}
}
if(!status){
satisfy(myisspace,mynothing);
putchar('(');
elementloop(myputchar,myputchar);
}
else if(status==1){
ungetc('(',stdin);
element(myputchar,myputchar);
}
putchar('\n');
}

Name: Anonymous 2021-03-28 12:54

>>10
I'll write it tomorrow, when I'll have some downtime at work.

Name: Anonymous 2021-03-28 13:09

>>17
Compare to the Symta runtime implementation C:
#:stdio:ctype:string

#DECL(ret, name, [xs]) {
struct name {
ret (*f)(struct name *,xs);
void *p;
}
}
...

Name: Anonymous 2021-03-28 13:59

>>18
rate mine >>17

Name: Anonymous 2021-03-28 16:09

Haskell version
#!/bin/env runhaskell
import System.Environment
import Text.Parsec
import Text.Parsec.Char
import Data.List

element = ((do char '('
spaces
x <- many (element >>= \x -> spaces >> return x) >>= return . intercalate " "
char ')'
return $ "(" ++ x ++ ")") <|> many1 digit)

work ('a':xs) = do spaces
char '('
spaces
element >>= setInput
work xs

work ('d':xs) = do spaces
char '('
spaces
element
getInput >>= \x -> setInput ('(':x)
work xs

work [] = element

main = do w <- getArgs >>= return . work . tail . reverse . tail . head
s <- getContents
putStrLn $ case runParser w () "stdin" s of
Left err -> show $ err
Right a -> a

Name: Anonymous 2021-03-29 7:06

The more I use JavaShit, the more I see that it's just like a retarded brother of LISP with a history of drug abuse.

lispify = function(js) {
if(Array.isArray(js)) {
return '(' + js.map(e => lispify(e)).join(' ') + ')';
} else {
return js;
};
}

delispify = function(sexp) {
let res = [];
for(let i=1; i<sexp.length-1; i++) {
c = sexp[i];

if(c >= '0' && c <= '9') {
n = c;
while(sexp[i+1] >= '0' && sexp[i+1] <= '9') {
n += sexp[++i];
}
res.push(n);
}

if(c == '(') {
parens = 1;
s = c;
while(parens) {
s += c = sexp[++i];
if(c == '(') {
parens++;
}
if(c == ')') {
parens--;
}
}

res.push(delispify(s));
}
}
return res;
}

progger = function(cudder, sexp) {
const cs = cudder.slice(1, -1).split('').reverse();
let res = delispify(sexp);
cs.forEach(c => res = (c == 'a' ? res[0] : res.slice(1)));
return lispify(res);
}

console.log('cdr', '(1 2 3 4)', progger('cdr', '(1 2 3 4)'));
console.log('car', '(1 2 3 4)', progger('car', '(1 2 3 4)'));
console.log('cddr', '(1 2 3 4)', progger('cddr', '(1 2 3 4)'));
console.log('cdddr', '(1 2 3 4)', progger('cdddr', '(1 2 3 4)'));
console.log('cadr', '(1 2 3 4)', progger('cadr', '(1 2 3 4)'));
console.log('car', '((1) 2 3 4)', progger('car', '((1) 2 3 4)'));
console.log('caar', '((1) 2 3 4)', progger('caar', '((1) 2 3 4)'));
console.log('cadr', '(1 (2 3 4))', progger('cadr', '(1 (2 3 4))'));

Name: Anonymous 2021-03-29 17:59

bump

Name: Anonymous 2021-03-30 12:51

Loose thought: it might be possible to make it a oneliner, by just skipping past a correct number of spaces and parens, depending on the cudder. I'll that soon!

Name: Anonymous 2021-03-30 15:00

I'll that soon too, but not a oneliner.

Name: Anonymous 2021-03-30 16:37

Did you know? When a /prague/rammer turns 18, his cdadrfather gives him a gift of cons-cells.

Name: Anonymous 2021-03-30 19:48

Still waiting for the Symta answer

Name: >>25 2021-03-31 6:27

Ok here's mine:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Node {
int valCar;
struct Node *car;
struct Node *cdr;
} Node;

struct Node * makeNode() {
return (struct Node *) malloc(sizeof(Node));
}

void parse(char **s, struct Node **n) {
while(**s)
switch(**s) {
case ')':
free(*n);
*n = NULL;
(*s)++;
return;
case ' ':
(*s)++;
continue;
case '(':
(*s)++;
(*n)->car = makeNode();
parse(s, &((*n)->car));
(*n)->cdr = makeNode();
n = &((*n)->cdr);
break;
default:
(*n)->valCar = strtol(*s, s, 10);
(*n)->cdr = makeNode();
n = &((*n)->cdr);
}
}

int printList(Node *n) {
if (!n->cdr) {
if (n->car) {
printf("(");
printList(n->car);
printf(")");
}
else {
printf("%d", n->valCar);
printf(")");
}
}
else if (n->car) {
printf("(");
printList(n->car);
printf(" ");
printList(n->cdr);
}
else {
printf("%d", n->valCar);
if (n->cdr) printf(" ");
printList(n->cdr);
}
return 0;
}

int format(Node *n) {
printf("(");
printList(n);
return printf("\n");
}

void eval(char *s, Node *n) {
int i = strlen(++s) - 1;
while (i-- > 1) {
n = (s[i] == 'a') ? n->car : n->cdr;
}
if (s[i] == 'a')
(!n->car) ? printf("%d\n", n->valCar) : format(n->car);
else
(n->cdr) ? format(n->cdr) : printf("()\n");
}

int main(int argc, char **argv) {
if (argc < 3) {
printf("Usage: ./cudder c[ad]+r <list>\n");
return 1;
}
struct Node *res = (struct Node *) malloc(sizeof(Node));
res->car = NULL;
res->cdr = NULL;
char *arg = argv[1];
char **s = &argv[2];
while (*(*s)++ == ' ');
parse(s, &res);
eval(arg, res);
}

Name: >>25 2021-03-31 6:31

Some tests: it handles random white spaces nicely.
$ gcc -o cudder -Wall -pedantic -Wextra cudder.c
$ ./cudder cadr "(1 (2 3 4))"
(2 3 4)
$ ./cudder cdr "(1)"
()
$ ./cudder caddadaaddr " (((((( ((((((((((1))))))))))))))) (( 2 3)) (( 4 (5 6 7)))) "
7
$ time ./cudder cadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddr "(1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0)"
0

real 0m0.001s
user 0m0.001s
sys 0m0.000s
$ time ./cudder caaaaaaaaaaaaaaaar "((((((((((((((((1))))))))))))))))"
1

real 0m0.001s
user 0m0.001s
sys 0m0.000s

Name: Anonymous 2021-03-31 6:43

inb4: I don't intend to collect garbage, it's a simple tree traversal

Name: Anonymous 2021-03-31 8:44

Just to relax:
#!/usr/bin/racket
#lang racket
(require srfi/13)
(define (anus arg lst)
(define (cudder str res)
(cond ((string-null? str)
res)
((eqv? (string-ref str 0) #\a)
(cudder (substring str 1) (car res)))
((eqv? (string-ref str 0) #\d)
(cudder (substring str 1) (cdr res)))))
(cudder (string-reverse arg 1 (- (string-length arg) 1)) lst))
(let ((v (current-command-line-arguments)))
(anus (vector-ref v 0)
(read (open-input-string (vector-ref v 1)))))


$ ./cudder caddar "((1 2 3) 2 (3))"
3

Name: Anonymous 2021-03-31 9:29

>>28-30
Alright, I'll collect the garbage.
diff -u /home/anon/prog/C/pointer.c /home/anon/prog/C/cudder.c
--- /home/anon/prog/C/dirty-cudder.c 2021-03-31 11:26:15.191784544 +0200
+++ /home/anon/prog/C/cudder.c 2021-03-31 11:24:53.851202993 +0200
@@ -80,6 +80,13 @@
(n->cdr) ? format(n->cdr) : printf("()\n");
}

+void clean(Node *n) {
+ if (!n) return;
+ clean(n->car);
+ clean(n->cdr);
+ free(n);
+}
+
int main(int argc, char **argv) {
if (argc < 3) {
printf("Usage: ./cudder c[ad]+r <list>\n");
@@ -93,4 +100,5 @@
while (*(*s)++ == ' ');
parse(s, &res);
eval(arg, res);
+ clean(res);
}


We good?

==2157233== HEAP SUMMARY:
==2157233== in use at exit: 0 bytes in 0 blocks
==2157233== total heap usage: 8 allocs, 8 frees, 1,192 bytes allocated
==2157233==
==2157233== All heap blocks were freed -- no leaks are possible

Name: Anonymous 2021-03-31 11:19

Good thread.

Name: Anonymous 2021-04-03 2:09

Name: Anonymous 2021-04-03 14:14

Well, fuck you assholes, nobody even dared to comment on my closures at >>17

Name: Anonymous 2021-04-03 14:33

>>35
Post them on Reddit and hackerNews if you want comments.

Name: Anonymous 2021-04-03 14:47

>>35
I'll give you one star on github if you want, just post a link.

Name: Anonymous 2021-04-03 16:01

>>35
discover typedef, dolt.

Name: Anonymous 2021-04-03 21:02

>>34
By mistake.

Name: Anonymous 2021-04-04 7:40

>>38
typedefs are against my religion.

Name: Anonymous 2021-04-04 11:05

Name: Anonymous 2021-04-04 17:21

>>41
error: expression is not assignable

Name: RAYNOR HERE 87 2021-04-05 8:12

my other car is a cudder!!
my other car is a cudder!!
my other car is a cudder who has been writing a browser!!
car cdr eval apply
car cdr eval apply
car cdr eval apply
we conjure the spirits of the 2008 /b/ with our autism
we conjure
we conjure BEING BACK SNACKS DESU DESU DESU DESU DESU DESU DESU DESU DESU DESU DESU

Name: Anonymous 2021-04-13 19:57

bump pant

Don't change these.
Name: Email:
Entire Thread Thread List