I would like to encrypt one line of text using the following encryption scheme.
This is the sample input. First, the spaces are removed from the text.
haveaniceday
Then, returns the length of a string (L = 12). Next, characters are written into a grid, whose rows and columns have the following constraints:
The length of a string will return the square root of L is between 3 and 4. Thus, rewritten with 3 rows and 4 columns:
have
anic
eday
Finally, the encoded message is obtained by displaying the characters in a column, inserting a space, and then displaying the next column and inserting a space, and so on.
For example, the encoded message for the above rectangle is:
hae and via ecy
In my code snippets, the grid ["have", "anic", "eday"] already created, but I have no idea how to achieve the next stage.
const s = "haveaniceday";
let result = encryption(s);
function encryption(s) {
let sqr = Math.sqrt(s.length),
col = Math.ceil(sqr),
row = Math.floor(sqr);
let chunks = chunkSubstr(s, col);
// => ["have", "anic", "eday"]
console.log(chunks);
for (var i = 0; i < chunks.length; i++) {
// do some magic here...
// expected output: "hae and via ecy"
}
}
function chunkSubstr(str, size) {
const numChunks = Math.ceil(str.length / size)
const chunks = new Array(numChunks)
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
chunks[i] = str.substr(o, size)
}
return chunks
}
You may reduce your Array ["have" "anic" "eday"] in an other Array, the length of your strings. For each three members of the original Array, you'll map all its characters into the new Array.
const original = ["have", "anic", "eday"];
const output = original.reduce((out, word) => {
word.split("") // break into characters[]
.forEach((char, i) =>
out[i] += char // append this char to the corresponding string of `out`
);
return out;
}, new Array(original[0].length).fill('')) // ['', '', '', '']
console.log(output.join(' '));
You may get each character in chunks by looping the count of col.
const s = "haveaniceday";
let result = encryption(s);
function encryption(s) {
let sqr = Math.sqrt(s.length),
col = Math.ceil(sqr),
row = Math.floor(sqr);
let chunks = chunkSubstr(s, col);
// => ["have", "anic", "eday"]
console.log(chunks);
let output = '';
for (var i=0; i<col; i++) {
chunks.forEach((e) => {
if (e[i]) {
output += e[i];
}
});
output += ' ';
}
console.log(output);
}
function chunkSubstr(str, size) {
const numChunks = Math.ceil(str.length / size)
const chunks = new Array(numChunks)
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
chunks[i] = str.substr(o, size)
}
return chunks
}
const s = "haveaniceday";
let result = encryption(s);
function encryption(s) {
let sqr = Math.sqrt(s.length),
col = Math.ceil(sqr),
row = Math.floor(sqr);
let chunks = chunkSubstr(s, col);
// => ["have", "anic", "eday"]
console.log(chunks);
var result = [];
for (var i = 0; i < chunks.length; i++) {
// do some magic here...
// expected output: "hae and via ecy"
var split = Array.from(chunks[i]);
for (var s = 0; s < split.length; s++) {
var previousValue = '';
if(result[s])
{ previousValue = result[s];}
result[s]=previousValue + split[s];
}
}
console.log(result);
}
function chunkSubstr(str, size) {
const numChunks = Math.ceil(str.length / size)
const chunks = new Array(numChunks)
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
chunks[i] = str.substr(o, size)
}
return chunks
}
easy => array.joint(' ') in the end, and a double loop
const s = "haveaniceday";
let result = encryption(s);
console.log ('result =', result );
function encryption(s) {
let
sqr = Math.sqrt(s.length),
col = Math.ceil(sqr),
row = Math.floor(sqr)
;
let chunks = chunkSubstr(s, col);
// => ["have", "anic", "eday"]
let Respons = [];
for (let i=0, iMax=chunks[0].length; i<iMax; i++ ) {
Respons[i] = '';
for (let txt of chunks ) {
Respons[i] += txt.charAt(i);
}
}
return Respons.join(' ');
}
function chunkSubstr(str, size) {
const
numChunks = Math.ceil(str.length / size),
chunks = new Array(numChunks)
;
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
chunks[i] = str.substr(o, size)
}
return chunks
}
Related
Hello I'm having a problem.
I want to create a triangular number pattern as follows:
Output:
1223334444333221
=22333444433322=
===3334444333===
======4444======
I've tried to make the program. But the logic I use is not quite right.
function nomor4(level) {
let len = null;
let result = [];
while (level > 0) {
let arr = [];
for (let i = 1; i < level; i++) {
for (let repeat = 0; repeat <i; repeat++){
arr.push(i)
}
}
// convert arr.push value from array to string using join
//and add 1 and the copy value using reverse
let str_level = arr.join("") + "4444" + arr.reverse().join("");
if (len == null) {
len = str_level.length;
}
//Add Strip
while (str_level.length < len) {
str_level = "-" + str_level + "-";
}
result.push(str_level);
level--;
}
return result.join("\n");
}
console.log(nomor4(4))
if anyone can. please help me give the solution. Thank you
Here's a way of doing this by using two nested maps over arrays of rows (a counter for each row) and columns (the values to print in each row)
const size = 4
const fill = '='
const rows = Array.from({length: size}, (_, i) => i + 1) // 1,2,3,4
const cols = rows.concat(rows.slice(0, -1).reverse()) // 1,2,3,4,3,2,1
const result = rows
.map(r => cols
.map(c => ((c >= r) ? c : fill).toString().repeat(c)
).join('')
).join('\n')
console.log(result)
There are better ways than this, but I will put this here just to show how to do it with minimal changes from the OP (I just changed - to = and the for loop with i).
function nomor4(level) {
let len = null;
let result = [];
while (level > 0) {
let arr = [];
for (let i = 5-level; i < 4; i++) {
for (let repeat = 0; repeat <i; repeat++){
arr.push(i)
}
}
// convert arr.push value from array to string using join
//and add 1 and the copy value using reverse
let str_level = arr.join("") + "4444" + arr.reverse().join("");
if (len == null) {
len = str_level.length;
}
//Add Strip
while (str_level.length < len) {
str_level = "=" + str_level + "=";
}
result.push(str_level);
level--;
}
return result.join("\n");
}
console.log(nomor4(4))
function nomor4(level) {
let realValue = level;
let len = null;
let result = [];
while (level >= 0) {
let arr = [];
for (let i = 1; i <= realValue; i++) {
if (realValue !== i) {
for (let repeat = 0; repeat < i; repeat++) {
if (realValue - level <= i) {
arr.push(i);
}
}
}
}
// convert arr.push value from array to string using join
// and add 1 and the copy value using reverse
let str_level = arr.join("") + "4444" + arr.reverse().join("");
if (len == null) {
len = str_level.length;
}
//Add Strip
while (str_level.length < len) {
str_level = "-" + str_level + "-";
}
result.push(str_level);
result = [...new Set(result)];
level--;
}
return result.join("\n");
}
console.log(nomor4(4));
I am trying to figure out how to make a function that takes a string. Then it needs to return a string with each letter that appears in the function along with the number of times it appears in the string. For instance "eggs" should return e1g2s1.
function charRepString(word) {
var array = [];
var strCount = '';
var countArr = [];
// Need an Array with all the characters that appear in the String
for (var i = 0; i < word.length; i++) {
if (array.indexOf(word[i]) === false) {
array.push(word[i]);
}
}
// Need to iterate through the word and compare it with each char in the Array with characters and save the count of each char.
for (var j = 0; j < word.length; i++) {
for (var k = 0; k < array.length; k++){
var count = 0;
if (word[i] === array[k]){
count++;
}
countArr.push(count);
}
// Then I need to put the arrays into a string with each character before the number of times its repeated.
return strCount;
}
console.log(charRepString("taco")); //t1a1co1
console.log(charRepString("egg")); //e1g2
let str = prompt('type a string ') || 'taco'
function getcount(str) {
str = str.split('')
let obj = {}
for (i in str) {
let char = str[i]
let keys = Object.getOwnPropertyNames(obj)
if (keys.includes(char)) {
obj[char] += 1
} else {
obj[char] = 1
}
}
let result = ''
Object.getOwnPropertyNames(obj).forEach((prop) => {
result += prop + obj[prop]
})
return result
}
console.log(getcount(str))
If the order of the alphanumeric symbols matters
const str = "10zza";
const counted = [...[...str].reduce((m, s) => (
m.set(s, (m.get(s) || 0) + 1), m
), new Map())].flat().join("");
console.log(counted); // "1101z2a1"
Or also like (as suggested by Bravo):
const str = "10zza";
const counted = [...new Set([...str])].map((s) =>
`${s}${str.split(s).length-1}`
).join("");
console.log(counted); // "1101z2a1"
A more clear and verbose solution-
Let m be max number of symbols in charset
Time complexity- O(n log(m))
Space complexity- O(m)
function countFrequencies(str) {
const freqs = new Map()
for (const char of str) {
const prevFreq = freqs.get(char) || 0
freqs.set(char, prevFreq + 1)
}
return freqs
}
function getCountStr(str) {
const freqs = countFrequencies(str)
const isListed = new Set()
const resultArray = []
for (const char of str) {
if (isListed.has(char)) continue
resultArray.push(char)
resultArray.push(freqs.get(char))
isListed.add(char)
}
return resultArray.join("")
}
console.log(getCountStr("egg"))
console.log(getCountStr("taco"))
console.log(getCountStr("10za"))
Using Set constructor, first we will get the unique data.
function myfun(str){
let createSet = new Set(str);
let newArr = [...createSet].map(function(elem){
return `${elem}${str.split(elem).length-1}`
});
let newStr = newArr.join('');
console.log(newStr);
}
myfun('array');
Is there a way to code a function that gets a string for example "Overflow!" and returns a random Permutation with the first, last and penultimate char staying the same?
Examples of the randomized string could be "Orfevolw!" or "Oervolfw!".
Thank you.
You need to pass the string and the constants number array that you don't want to change.
const generateString = (str, constants = []) => {
const strArray = str.split("");
const result = Array(str.length)
.fill("")
.map((s, i) => {
if (constants.includes(i))
return strArray.splice(i - (str.length - strArray.length), 1);
return "";
});
for (let i = 0; i < result.length; ++i) {
if (!result[i]) {
const random = Math.floor(Math.random() * strArray.length);
result[i] = strArray.splice(random, 1);
}
}
return result.join("");
};
console.log(generateString("Overflow!", [0, 7, 8]));
console.log(generateString("Overflow!"));
Use string.randomize function ( I created this function returns randomly arranged string) on string variable
String.prototype.randomize = function() {
let str = "";
let array = [];
for (var i = 0; i < this.length; i++) {
array.push(this[i])
}
array.sort(() => 0.5 - Math.random());
array.forEach(word => {
str += word
})
return str;
}
let str = "Overflow";
// Calling .randomzie function
str = str.randomize()
// Logging it
console.log(str)
I am trying to create n number of arrays in a new array(multipleArrays). Next step is to find duplicates in that multipleArrays and how many times they repeat. I am using 2 functions. First one is to create the main array with 35 numbers out of 48 numbers. The second function is gathering all those arrays into one array.
function createArray35() {
const array35 = [];
i = 0;
do {
var rng = Math.floor(Math.random() * 48) + 1;
if (!array35.includes(rng)) {
array35.push(rng);
i++;
}
}
while (i < 35)
return array35
}
createArray35();
function multipleArray(total_number) {
var arrayOfArrays = [];
for (z = 0; z <= total_number; z++) {
var array35 = createArray35();
arrayOfArrays.push(niz35)
}
return arrayOfArrays;
}
var total_arrays = 3; // total number of "array35" I want to ceate in
// "multipleArray"
console.log(multipleArray(arrayOfArrays));
Expected result should be:
Number 1 is repeated (n) times;
Number 2 is repeated (n) times;
...
...
Number 47 is repeated (n) times
Number 48 is repeated (n) times
Thank you all in advance
Code with comments:
// This method of getting X unique numbers from Y set is recommended, because it has a stable execution time
function createArray35() {
// create a [1 .... 48] array
var candidates = Array.from({
length: 48
}).map((el, index) => index + 1);
var array35 = [];
for (var i = 0; i < 35; i++) {
// remove 1 random number from candidates
const positionToRemove = Math.floor(Math.random() * candidates.length);
const randomNum = candidates.splice(
positionToRemove,
1
)[0];
array35.push(randomNum);
}
return array35
}
function multipleArray(total_number) {
var arrayOfArrays = Array.from({
length: total_number
}).map(el => createArray35());
return arrayOfArrays;
}
function countDuplicates(arrayOfArrays) {
// Create an array of length 48 where each element is 0;
var counters = Array.from({
length: 48
}).map(el => 0);
// Each time a number appear, increase its corresponding counter by 1
for (var array of arrayOfArrays) {
for (var number of array) {
counters[number - 1] = counters[number - 1] + 1;
}
}
for (var i = 0; i < counters.length; i++) {
console.log(`Number ${i+1} is repeated ${counters[i]} times;`);
}
}
var total_arrays = 3;
var arrayOfArrays = multipleArray(total_arrays);
console.log(arrayOfArrays);
countDuplicates(arrayOfArrays);
function createArray35() {
const array35 = [];
i = 0;
do {
var rng = Math.floor(Math.random() * 48) + 1;
if (!array35.includes(rng)) {
array35.push(rng);
i++;
}
}
while (i < 35)
return array35;
}
function CalculateCount(array){
var result = {};
for(let i=0;i<array.length;i++){
var obj = array[i].toString();
if(result[obj]){
result[obj] = result[obj]+1;
}
else{
result[obj] = 1;
}
}
return result;
}
function PrintResult(result){
for(var i in result){
console.log(`Number ${i} is repeated (${result[i]}) times;`);
}
}
var resultObject = CalculateCount(createArray35());
PrintResult(resultObject);
Impressed by the possibilities of neural networks, I've decided that before using any library I want to understand how they work. So I wrote a simple training app, which used 3 layer network with 2 neurons each. There was a canvas 400x400. Given the coordinates of x,y of the mouse over the canvas <0;399> it was supposed to give as the result coordinate/400 <0;1> (So for 100,300 it is supposed to give 0.25,0.75).
The training looked reasonable.
But when I switch to the prediction mode the network gives the same result all the time for each training batch. It gives the same results no matter what the input is.
Then after more training the output changes, but it’s still the same for each input.
It's written in TypeScript.
Instead of pasting the whole web training page I just made the training script so you can see more clearly what's going on.
index.ts
let sigmoid: ActivationFunction = {
func: (x: number) => (1 / (1 + Math.exp(-x))),
derivative: (z: number) => {
return sigmoid.func(z) * (1 - sigmoid.func(z));
}
};
import Matrix from './matrix';
class NeutralNetwork {
layers: Array<number>;
weights: Matrix[];
biases: Matrix[];
activation_function: ActivationFunction;
learning_rate: number;
constructor(...layers: Array<number>) {
this.layers = layers;
this.activation_function = sigmoid;
//Initialize neural network with random weigths and biases [-1;1]
this.weights = [];
for(let i=0; i<this.layers.length - 1; i++){
this.weights.push(new Matrix(this.layers[i+1], this.layers[i]));
this.weights[i].randomize();
}
this.biases = [];
for(let i=1; i<this.layers.length; i++){
this.biases.push(new Matrix(this.layers[i], 1));
this.biases[i-1].randomize();
}
this.setActivationFunction();
this.setLearningRate();
}
feedForward(originalInput: Array<number>): Array<number> {
if(originalInput.length != this.layers[0]) throw new Error("corrupt input data");
let input : Matrix = Matrix.createFromArray(originalInput);
for(let i = 0; i < this.layers.length - 1; i++){
let output = Matrix.multiply(this.weights[i], input);
output.add(this.biases[i]);
output.map(this.activation_function.func);
input = output;
}
return input.toArray();
}
train(originalInput: Array<number>, originalTarget: Array<number>) {
if(originalInput.length != this.layers[0]) throw new Error("corrupt training data");
if(originalTarget.length != this.layers[this.layers.length - 1]) throw new Error("corrupt training data");
let outputs : Matrix[] = [];
let input : Matrix = Matrix.createFromArray(originalInput);
for(let i = 0; i < this.layers.length - 1; i++){
let output = Matrix.multiply(this.weights[i], input);
output.add(this.biases[i]);
output.map(this.activation_function.func);
input = output;
outputs.push(output);
}
let target = Matrix.createFromArray(originalTarget);
let errors = Matrix.subtract(target, outputs[this.layers.length - 2]);
for(let i = this.layers.length - 2; i>=0; i--){
let gradients = Matrix.map(outputs[i], this.activation_function.derivative);
gradients.multiply(errors);
gradients.multiply(this.learning_rate);
let outputsOfLayerBeforeTransposed = Matrix.transpose(i > 0 ? outputs[i-1] : Matrix.createFromArray(originalInput));
let deltas = Matrix.multiply(gradients, outputsOfLayerBeforeTransposed);
this.weights[i].add(deltas);
this.biases[i].add(gradients);
let weightsTransposed = Matrix.transpose(this.weights[i]);
errors = Matrix.multiply(weightsTransposed, errors);
}
return outputs[outputs.length - 1].toArray();
}
setActivationFunction(activationFunction = sigmoid) {
this.activation_function = activationFunction;
}
setLearningRate(learning_rate = 0.1) {
this.learning_rate = learning_rate;
}
}
interface ActivationFunction {
func(x: number): number;
derivative(x: number): number;
}
export = NeutralNetwork;
training.ts
let NN = require('./index');
let n = new NN(2,2,2);
let data = generateTrainingData();
data.forEach(d => n.train(d.i, d.o));
//check how well is it trained
let index = 0
let t = setInterval(()=>{
let pred = n.feedForward(data[index].i);
console.log(`PREDICTED - ${pred} EXPECTED = ${data[index].o} COST - ${Math.pow(pred[0]-data[index].o[0],2)+Math.pow(pred[1]-data[index].o[1],2)}`)
if(index++ == 1000) clearInterval(t);
}, 500);
function generateTrainingData(){
let data = [];
for(let i=0;i<1000;i++){
let x = Math.floor(Math.random() * 400);
let y = Math.floor(Math.random() * 400);
data.push({
i : [x,y],
o : [x/400, y/400]
})
}
return data;
}
matrix.ts
export default class Matrix {
rows;
columns;
data: Array<Array<number>>;
constructor(rows, columns) {
this.rows = rows;
this.columns = columns;
this.data = new Array(this.rows).fill().map(() => Array(this.columns).fill(0));
}
static map(matrix, f) : Matrix{
let m = new Matrix(matrix.rows, matrix.columns);
m.map((v,i,j) => f(matrix.data[i][j], i, j));
return m;
}
map(f) {
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.columns; j++) {
this.data[i][j] = f(this.data[i][j], i, j);
}
}
}
randomize() {
this.map(() => Math.random() * 2 - 1);
}
add(n) {
if (n instanceof Matrix) {
if (this.rows !== n.rows || this.columns !== n.columns) {
throw new Error('Size of both matrices must match!');
}
return this.map((v, i, j) => v + n.data[i][j]);
} else {
return this.map(v => v + n);
}
}
static subtract(a, b) : Matrix{
if (a.rows !== b.rows || a.columns !== b.columns) {
throw new Error('Size of both matrices must match!');
}
let m = new Matrix(a.rows, a.columns);
m.map((_, i, j) => a.data[i][j] - b.data[i][j]);
return m;
}
static multiply(a, b) {
if (a.columns !== b.rows) {
throw new Error('a.columns !== b.rows');
}
let m = new Matrix(a.rows, b.columns)
m.map((_, i, j) => {
let sum = 0;
for (let k = 0; k < a.cols; k++) {
sum += a.data[i][k] * b.data[k][j];
}
return sum;
});
return m;
}
multiply(n) {
if (n instanceof Matrix) {
if (this.rows !== n.rows || this.columns !== n.columns) {
throw new Error('Size of both matrices must match!');
}
return this.map((v, i, j) => v * n.data[i][j]);
} else {
return this.map(v => v * n);
}
}
toArray() {
let arr = [];
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.columns; j++) {
arr.push(this.data[i][j]);
}
}
return arr;
}
static transpose(matrix) : Matrix {
let m = new Matrix(matrix.columns, matrix.rows)
m.map((_, i, j) => matrix.data[j][i]);
return m;
}
static createFromArray(arr): Matrix {
let m = new Matrix(arr.length, 1);
m.map((v, i) => arr[i]);
return m;
}
}
I'm not really sure what the cause of that. I've been trying to debug this for days now, but I think my lack of experience doesn't let me see the issue here. Thank you so much for all of your help.
There is a mistake in Matrix.multiply class method. It should be a.columns rather than a.cols. Because of this, gradients and deltas are not updating properly.