Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Challenges

Post History

60%
+1 −0
Challenges Sort letters by height

C (gcc), 152 bytes r;e(c){r=c=='j'?5:strchr("bdfghklpqy",c)?4:c=='i'?3:c=='t'?2:1;}c;s;f(char*i,char*o){s?(e(*i),c=r,e(*o)):(qsort(i,strlen(i),s=1,f),puts(i));return r-c;} Try it online! Out...

posted 2y ago by Lundin‭  ·  edited 2y ago by trichoplax‭

Answer
#2: Post edited by user avatar trichoplax‭ · 2022-11-03T15:12:13Z (about 2 years ago)
Mark code block as text to avoid syntax highlighting making the first letter bold
  • # [C (gcc)], 152 bytes
  • <!-- language-all: lang-c -->
  • r;e(c){r=c=='j'?5:strchr("bdfghklpqy",c)?4:c=='i'?3:c=='t'?2:1;}c;s;f(char*i,char*o){s?(e(*i),c=r,e(*o)):(qsort(i,strlen(i),s=1,f),puts(i));return r-c;}
  • [Try it online!][TIO-l9zmnipy]
  • [C (gcc)]: https://gcc.gnu.org/
  • [TIO-l9zmnipy]: https://tio.run/##Vcy9boMwEAfwnac40QE7ciTox4JlMfUJmi3KQA4TTFKb2KYlRTw7NclQOt397uOP2xPiPFsuCdLRChQiaZPiLXfeYmNJfKzqU3O@dNdbzJAWr/lyoZLi5d74pHjOMz4hd7wm2JR2o9i9GDq6gkiyUZShsCx0htKcXJ2xnigW8i9Sk7B1ImM1ZV3vXSDlVvrearBb5NP8VMlaaQm7948dGSiMsKRD@N4fQMDAHza932dpeuBQk7BjwZSDEymHKYqU9vBZKg3ky6iKRmMEj8C4jCn/w395dWzXA6/wvLY232u2vfNrd@2Pv6lhGU3zLw "C (gcc) – Try It Online"
  • Output:
  • ```
  • a
  • aa
  • jbita
  • kitc
  • now
  • jtus
  • jpyitzx
  • ```
  • I didn't fine tune it much, but it's delightfully crazy :)
  • Explanation:
  • - The function `f` takes one input string and one output string as parameter. It returns `int` as per gcc's old C90 default behavior.
  • - Since in-place modification of the input should be fine according to Codidacts input/output rules, I actually never use the output but modify the input. (Would crash & burn in case of string literals though, but the challenge only said strings, so I skipped the copy from input to output buffer.)
  • - The global variable `s` gets zero-initialized and is used to mark the function's state. If not set, then it's the first call. If set, then the function has been called before. (This will have to be reset to zero externally, in order to execute multiple test cases in a row from main())
  • - `s?` checks if `s` is zero, if so execute `qsort` and then print.
  • - `qsort` uses the very same function `f` as its own callback to save a function. This abuses the fact that `const void*` and `char*` likely have the same representation. And the function returns `int` so it fulfils the requirements of a qsort callback. Curiously, `qsort` didn't raise a compiler error when passed the wrong type of function pointer (this doesn't sound conforming at all, gcc...).
  • - When `qsort` is called, the size of one item parameter also sets the state `s` to 1.
  • - `f` gets called by `qsort` many times and now the `s?` evaluates to 1. It calls the helper function `e` to evaluate both parameters (`i` and `o` are now the qsort callback parameters).
  • - `e` sets a global variable `r` to value 5,4,3,2 or 1 depending on how which set of characters the passed character belongs to.
  • - No benefit from typing out decimal values of these characters since they are all above ASCII value 100, might as well use `'a'` character constants then.
  • - The result `r` from the first call to `e` is stored in `c`. Then after the next call `r-c` is returned as the result of qsort callback. This weighs `'j'` as lowest, swap to `c-r` to get the other way around.
  • - The function actually always returns `r-c` but when `s==0` nobody cares since the result is placed in the `i` buffer anyway.
  • - When `qsort` is done, we are back to the first execution of the function, so `puts` is called once before finishing.
  • # [C (gcc)], 152 bytes
  • <!-- language-all: lang-c -->
  • r;e(c){r=c=='j'?5:strchr("bdfghklpqy",c)?4:c=='i'?3:c=='t'?2:1;}c;s;f(char*i,char*o){s?(e(*i),c=r,e(*o)):(qsort(i,strlen(i),s=1,f),puts(i));return r-c;}
  • [Try it online!][TIO-l9zmnipy]
  • [C (gcc)]: https://gcc.gnu.org/
  • [TIO-l9zmnipy]: https://tio.run/##Vcy9boMwEAfwnac40QE7ciTox4JlMfUJmi3KQA4TTFKb2KYlRTw7NclQOt397uOP2xPiPFsuCdLRChQiaZPiLXfeYmNJfKzqU3O@dNdbzJAWr/lyoZLi5d74pHjOMz4hd7wm2JR2o9i9GDq6gkiyUZShsCx0htKcXJ2xnigW8i9Sk7B1ImM1ZV3vXSDlVvrearBb5NP8VMlaaQm7948dGSiMsKRD@N4fQMDAHza932dpeuBQk7BjwZSDEymHKYqU9vBZKg3ky6iKRmMEj8C4jCn/w395dWzXA6/wvLY232u2vfNrd@2Pv6lhGU3zLw "C (gcc) – Try It Online"
  • Output:
  • ```text
  • a
  • aa
  • jbita
  • kitc
  • now
  • jtus
  • jpyitzx
  • ```
  • I didn't fine tune it much, but it's delightfully crazy :)
  • Explanation:
  • - The function `f` takes one input string and one output string as parameter. It returns `int` as per gcc's old C90 default behavior.
  • - Since in-place modification of the input should be fine according to Codidacts input/output rules, I actually never use the output but modify the input. (Would crash & burn in case of string literals though, but the challenge only said strings, so I skipped the copy from input to output buffer.)
  • - The global variable `s` gets zero-initialized and is used to mark the function's state. If not set, then it's the first call. If set, then the function has been called before. (This will have to be reset to zero externally, in order to execute multiple test cases in a row from main())
  • - `s?` checks if `s` is zero, if so execute `qsort` and then print.
  • - `qsort` uses the very same function `f` as its own callback to save a function. This abuses the fact that `const void*` and `char*` likely have the same representation. And the function returns `int` so it fulfils the requirements of a qsort callback. Curiously, `qsort` didn't raise a compiler error when passed the wrong type of function pointer (this doesn't sound conforming at all, gcc...).
  • - When `qsort` is called, the size of one item parameter also sets the state `s` to 1.
  • - `f` gets called by `qsort` many times and now the `s?` evaluates to 1. It calls the helper function `e` to evaluate both parameters (`i` and `o` are now the qsort callback parameters).
  • - `e` sets a global variable `r` to value 5,4,3,2 or 1 depending on how which set of characters the passed character belongs to.
  • - No benefit from typing out decimal values of these characters since they are all above ASCII value 100, might as well use `'a'` character constants then.
  • - The result `r` from the first call to `e` is stored in `c`. Then after the next call `r-c` is returned as the result of qsort callback. This weighs `'j'` as lowest, swap to `c-r` to get the other way around.
  • - The function actually always returns `r-c` but when `s==0` nobody cares since the result is placed in the `i` buffer anyway.
  • - When `qsort` is done, we are back to the first execution of the function, so `puts` is called once before finishing.
#1: Initial revision by user avatar Lundin‭ · 2022-11-02T13:00:38Z (about 2 years ago)
# [C (gcc)], 152 bytes

<!-- language-all: lang-c -->

    r;e(c){r=c=='j'?5:strchr("bdfghklpqy",c)?4:c=='i'?3:c=='t'?2:1;}c;s;f(char*i,char*o){s?(e(*i),c=r,e(*o)):(qsort(i,strlen(i),s=1,f),puts(i));return r-c;}

[Try it online!][TIO-l9zmnipy]

[C (gcc)]: https://gcc.gnu.org/
[TIO-l9zmnipy]: https://tio.run/##Vcy9boMwEAfwnac40QE7ciTox4JlMfUJmi3KQA4TTFKb2KYlRTw7NclQOt397uOP2xPiPFsuCdLRChQiaZPiLXfeYmNJfKzqU3O@dNdbzJAWr/lyoZLi5d74pHjOMz4hd7wm2JR2o9i9GDq6gkiyUZShsCx0htKcXJ2xnigW8i9Sk7B1ImM1ZV3vXSDlVvrearBb5NP8VMlaaQm7948dGSiMsKRD@N4fQMDAHza932dpeuBQk7BjwZSDEymHKYqU9vBZKg3ky6iKRmMEj8C4jCn/w395dWzXA6/wvLY232u2vfNrd@2Pv6lhGU3zLw "C (gcc) – Try It Online"

Output:

```
a
aa
jbita
kitc
now
jtus
jpyitzx
```

I didn't fine tune it much, but it's delightfully crazy :)

Explanation:

- The function `f` takes one input string and one output string as parameter. It returns `int` as per gcc's old C90 default behavior.
- Since in-place modification of the input should be fine according to Codidacts input/output rules, I actually never use the output but modify the input. (Would crash & burn in case of string literals though, but the challenge only said strings, so I skipped the copy from input to output buffer.)
- The global variable `s` gets zero-initialized and is used to mark the function's state. If not set, then it's the first call. If set, then the function has been called before. (This will have to be reset to zero externally, in order to execute multiple test cases in a row from main())
- `s?` checks if `s` is zero, if so execute `qsort` and then print.
- `qsort` uses the very same function `f` as its own callback to save a function. This abuses the fact that `const void*` and `char*` likely have the same representation. And the function returns `int` so it fulfils the requirements of a qsort callback. Curiously, `qsort` didn't raise a compiler error when passed the wrong type of function pointer (this doesn't sound conforming at all, gcc...).
- When `qsort` is called, the size of one item parameter also sets the state `s` to 1.
- `f` gets called by `qsort` many times and now the `s?` evaluates to 1. It calls the helper function `e` to evaluate both parameters (`i` and `o` are now the qsort callback parameters).
- `e` sets a global variable `r` to value 5,4,3,2 or 1 depending on how which set of characters the passed character belongs to.
- No benefit from typing out decimal values of these characters since they are all above ASCII value 100, might as well use `'a'` character constants then.
- The result `r` from the first call to `e` is stored in `c`. Then after the next call `r-c` is returned as the result of qsort callback. This weighs `'j'` as lowest, swap to `c-r` to get the other way around.
- The function actually always returns `r-c` but when `s==0` nobody cares since the result is placed in the `i` buffer anyway.
- When `qsort` is done, we are back to the first execution of the function, so `puts` is called once before finishing.