Some solutions for the julia path

This commit is contained in:
2025-08-04 19:44:03 +02:00
parent 5c52e8e34d
commit 8296c79f68
104 changed files with 4373 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
{
"authors": [
"colinleach"
],
"files": {
"solution": [
"secrets.jl"
],
"test": [
"runtests.jl"
],
"exemplar": [
".meta/exemplar.jl"
]
},
"forked_from": [
"java/secrets"
],
"blurb": "Learn about bit manipulation by writing a program to decrypt a message."
}

View File

@@ -0,0 +1 @@
{"track":"julia","exercise":"secrets","id":"3bbfeb59334b4b14a09c7f5a345b04e5","url":"https://exercism.org/tracks/julia/exercises/secrets","handle":"Kimawari","is_requester":true,"auto_approve":false}

34
julia/secrets/HELP.md Normal file
View File

@@ -0,0 +1,34 @@
# Help
## Running the tests
To run the tests, run this command from within the exercise directory:
```bash
$ julia runtests.jl
```
## Submitting your solution
You can submit your solution using the `exercism submit secrets.jl` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Julia track's documentation](https://exercism.org/docs/tracks/julia)
- The [Julia track's programming category on the forum](https://forum.exercism.org/c/programming/julia)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, we recommend that you submit your code and request mentoring :)
If you don't want to do that for whatever reason, then you can find the wider Julia community channels [here](https://julialang.org/community/).

21
julia/secrets/HINTS.md Normal file
View File

@@ -0,0 +1,21 @@
# Hints
Some (not all) of the tests assume the value is `Int32`, so please avoid forcing it to be anything else.
## 1. Shift back the bits
- This is a right-shift.
- Note the instruction that the results should be left-filled with zeros.
## 2. Set some bits
- Bits are set by bitwise OR with a mask. This is extremely common.
## 3. Flip specific bits
- There is an old joke among programmers that cryptographers discovered XOR and forgot to read the rest of the manual.
## 4. Clear specific bits
- Simple AND logic will do the opposite of what you need.
- How do you flip all the bits in the mask?

185
julia/secrets/README.md Normal file
View File

@@ -0,0 +1,185 @@
# Secrets
Welcome to Secrets on Exercism's Julia Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
## Introduction
Binary digits ultimately map directly to the transistors in your CPU or RAM, and whether each is "on" or "off".
Low-level manipulation, informally called "bit-twiddling", is particularly important in system languages.
High-level languages like Julia usually abstract away most of this detail.
However, a full range of bit-level operations are available in the base language.
***Note:*** To see human-readable binary output in the REPL, nearly all the examples below need to be wrapped in a `bitstring()` function.
This is visually distracting, so most occurrences of this function have been edited out.
## Bit-shift operations
Integer types, signed or unsigned, can be represented as a string of 1's and 0's.
```julia-repl
julia> bitstring(UInt8(5))
"00000101"
```
Bit-shifts just move everything to the left or right by a specified number of positions.
With `UInt` types, some bits drop off one end, and the other end is padded with zeros:
```julia-repl
julia> ux::UInt8 = 5
5
julia> bitstring(ux)
"00000101"
julia> ux << 2 # left by 2
"00010100"
julia> ux >> 1 # right by 1
"00000010"
```
Each left-shift doubles the value and each right-shift halves it (subject to truncation).
This is more obvious in decimal representation:
```julia-repl
julia> 3 << 2
12
julia> 24 >> 3
3
```
Such bit-shifting is much faster than "proper" arithmetic, making the technique very popular in low-level coding.
With signed integers, we need to be a bit more careful.
Left shifts are relatively simple:
```julia-repl
julia> sx = Int8(5)
5
julia> sx # positive integer
"00000101"
julia> sx << 2
"00010100"
julia> -sx # negative integer
"11111011"
julia> -sx << 2
"11101100"
```
Left-shifting positive signed integers is thus the same as with unsigned integers.
Negative values are stored in [two's complement][2complement] form, which means that the left-most bit is 1.
No problem for a left-shift, but when right-shifting how do we pad the left-most bits?
```julia-repl
julia> sx >> 2 # simple for positive values!
"00000001"
julia> -sx # negative integer
"11111011"
julia> -sx >> 2 # pad with repeated sign bit
"11111110"
julia> -sx >>> 2 # pad with 0
"00111110"
```
The `>>` operator performs arithmetic shift, preserving the sign bit.
The `>>>` operator performs logical shift, padding with zeros as if the number was unsigned.
## Bitwise logic
We saw in a previous Concept that the operators `&&` (and), `||` (or) and `!` (not) are used with boolean values.
There are equivalent operators `&` (bitwise and), `|` (bitwise or) and `~` (a tilde, bitwise not) to compare the bits in two integers.
```julia-repl
julia> 0b1011 & 0b0010 # bit is 1 in both numbers
"00000010"
julia> 0b1011 | 0b0010 # bit is 1 in at least one number
"00001011"
julia> ~0b1011 # flip all bits
"11110100"
julia> xor(0b1011, 0b0010) # bit is 1 in exactly one number, not both
"00001001"
```
Here, `xor()` is exclusive-or, used as a function.
[2complement]: https://en.wikipedia.org/wiki/Two%27s_complement
## Instructions
Your friend has just sent you a message with an important secret.
Not wanting to make it easy for others to read it, the message was encrypted by performing a series of bit manipulations.
You will need to write the functions to help decrypt the message.
## 1. Shift back the bits
The first step in decrypting the message is to undo the shifting from the encryption process by shifting the bits back to the right.
There will be further steps in the decryption process that assume 0s are inserted from the left hand side.
Implement the `shift_back()` function that takes a value and the number of places to shift and peforms the shift.
```julia
shift_back(0b1001, 2) # => 0b0010
```
## 2. Set some bits
Next, there are some bits that need to be set to 1.
Implement the `set_bits()` function that takes a value and a mask and returns the result of setting the bits in value to 1.
A bit from `value` should be set to 1 where the bit in the `mask` is also 1.
All other bits should be kept unchanged.
```julia
set_bits(0b0110, 0b0101) # => 0b0111
```
## 3. Flip specific bits
Some bits are flipped during encryption.
They will need to be flipped back to decrypt the message.
Implement the `flip_bits()` function that takes a value and the mask.
The mask indicates which bits in the value to flip.
If the bit is 1 in `mask`, the bit is flipped in the `value`.
All other bits are kept unchanged.
```julia
flip_bits(0b1100, 0b0101) # => 0b1001
```
## 4. Clear specific bits
Lastly, there are also certain bits that always decrypt to 0.
Implement the `clear_bits()` function that takes a value and a mask.
The bits in the `value` should be set to 0 where the bit in the mask is 1.
All other bits should be kept unchanged.
```julia
clear_bits(0b0110, 0b0101) # => 0b0010
```
## Source
### Created by
- @colinleach

30
julia/secrets/runtests.jl Normal file
View File

@@ -0,0 +1,30 @@
using Test
include("secrets.jl")
@testset verbose = true "tests" begin
@testset "1. Shift back the bits" begin
@test shift_back(8, 2) == 2
# The original Java code uses a signed integer, so we use Int32 here
# Fails with Int64!
@test shift_back(Int32(-2_144_333_657), 3) == 268_829_204
end
@testset "2. Set bits" begin
@test set_bits(5, 3) == 7
@test set_bits(5_652, 26_150) == 30_262
end
@testset "3. Flip bits" begin
@test flip_bits(5, 11) == 14
@test flip_bits(38_460, 15_471) == 43_603
end
@testset "4. Clear bits" begin
@test clear_bits(5, 11) == 4
@test clear_bits(90, 240) == 10
end
end

15
julia/secrets/secrets.jl Normal file
View File

@@ -0,0 +1,15 @@
function shift_back(value, amount)
return value >>> amount
end
function set_bits(value, mask)
return value | mask
end
function flip_bits(value, mask)
return value mask
end
function clear_bits(value, mask)
return value & ~mask
end